我有两个词典,一个包含原始数据,另一个包含新数据。我想比较两个词典并返回一个词典并返回包含更新的第三个词典。
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"}},
}
我想获得包含更新的第三个字典。它可以是整个第一级,也可以分为第二级。以下两个例子对我都有用。
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"}}
}
我已经尝试过这篇文章How to compare two Dictionaries in 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);
还有其他方法可以解决这个问题吗?
谢谢!
答案 0 :(得分:2)
首先是简单的部分。找到已添加或删除的密钥:
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]));