2014-02-11 52 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

相關問題