我有两个字典,一个包含原始数据,另一个包含新数据。我想比较两个词典并返回一个词典并返回第三个包含更新的词典。
Dictionary<int, Dictionary<string, string>> OriginalDictionary = new Dictionary
{
{1, new Dictionary<string, string>
{{"name", "adam"},
{"age", "15"}
{"occupation", "student"}},
{2, new Dictionary<string, string>
{{"name", "bob"},
{"age", "40"}
{"occupation", "doctor"}},
{3, new Dictionary<string, string>
{{"name", "cameron"},
{"age", "32"}
{"occupation", "teacher"}},
}
Dictionary<int, Dictionary<string, string>> NewDictionary = new Dictionary
{
{1, new Dictionary<string, string>
{{"name", "adam"},
{"age", "15"}
{"occupation", "student"}},
{2, new Dictionary<string, string>
{{"name", "bob"},
{"age", "40"}
{"occupation", "lawyer"}}, //this is where it's different
{3, new Dictionary<string, string>
{{"name", "cameron"},
{"age", "32"}
{"occupation", "teacher"}},
}
我想获得包含更新的第三本字典。它可以是整个第一级,也可以分解成第二级。以下 2 个示例都对我有用。
Dictionary<int, Dictionary<string, string>> UpdateDictionary1 = new Dictionary
{
{2, new Dictionary<string, string>
{{"name", "bob"},
{"age", "40"}
{"occupation", "lawyer"}} //this is where it's different
}
Dictionary<int, Dictionary<string, string>> UpdateDictionary2 = new Dictionary
{
{2, new Dictionary<string, string>
{{"occupation", "lawyer"}}
}
我已经尝试了这篇文章中的答案 如何在C#中比较两个字典,但我为UpdateDictionary获得的结果仍然包含来自NewDictionary的所有数据。 UpdatesDictionary.Count == 3
,我的预期输出应该是UpdatesDictionary.Count == 1
。我尝试了Where
答案和Except
答案,但它们都没有像我想要的那样工作。
UpdateDictionary = OriginalDictionary.Where(entry => NewDictionary[entry.Key] != entry.Value).ToDictionary(entry => entry.Key, entry => entry.Value);
UpdateDictionary = OriginalDictionary.Except(NewDictionary).ToDictionary(x => x.Key, x => x.Value);
我应该有其他方法吗?
谢谢!
所以首先是简单的部分。 查找已添加或删除的密钥:
var addedKeys = NewDictionary.Keys.Except(OriginalDictionary.Keys);
var removedKeys = OriginalDictionary.Keys.Except(NewDictionary.Keys);
接下来,为了找到具有编辑字典的键,我们将为字典创建一个相等比较器,仅仅是因为试图内联它们可能不同的所有可能方式会太多。
public class DictionaryComparer<TKey, TValue> :
IEqualityComparer<Dictionary<TKey, TValue>>
{
private IEqualityComparer<TValue> valueComparer;
public DictionaryComparer(IEqualityComparer<TValue> valueComparer = null)
{
this.valueComparer = valueComparer ?? EqualityComparer<TValue>.Default;
}
public bool Equals(Dictionary<TKey, TValue> x, Dictionary<TKey, TValue> y)
{
if (x.Count != y.Count)
return false;
if (x.Keys.Except(y.Keys).Any())
return false;
if (y.Keys.Except(x.Keys).Any())
return false;
foreach (var pair in x)
if (!valueComparer.Equals(pair.Value, y[pair.Key]))
return false;
return true;
}
public int GetHashCode(Dictionary<TKey, TValue> obj)
{
throw new NotImplementedException();
}
}
现在我们有了这个,调用它非常简单:
var addedKeys = NewDictionary.Keys.Except(OriginalDictionary.Keys);
var removedKeys = OriginalDictionary.Keys.Except(NewDictionary.Keys);
var comparer = new DictionaryComparer<string, string>();
var editedValues = OriginalDictionary.Where(pair =>
!comparer.Equals(pair.Value, NewDictionary[pair.Key]));