2014-02-11 50 views
1

我有两个词典,一个包含原始数据,另一个包含新数据。我想比较这两个字典并返回一个字典并返回包含更新的第三个字典。比较两个词典并返回差异

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 == 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); 

有没有其他方法我应该这样做?

谢谢!

回答

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])); 
+0

谢谢你的答复。编辑值的数目仍然没有出来。我仍然得到更多的更新比应该是:/ – sora0419

+0

@ sora0419对不起,错过了不在那里;它得到所有的平等字典。 – Servy

+0

我仍然得到一个更大数量的计数,所以我试图使用Trim()来摆脱我不知道的额外空间,并最终让它正常工作(至少现在我没有看到任何问题) 。非常感谢! – sora0419

相关问题