2013-02-13 153 views
3

這是與這個問題有關,關於如何合併C#中的兩個字典。展示了一個優雅的Linq解決方案,這很酷。合併兩個字典字典<字符串,字典<字符串,對象>>

但是,該問題涉及到Dictionary<Object1, Object2>,而我有一個字典,其值爲Dictionary<string, Object>

我要尋找一個解決方案用於合併拖Dictionary<string, Dictionary<string, Object>>,符合下列要求:

  • 沒有兩個詞典的詞典結果複製鍵,
  • 對於每個字典我認爲KEY分組可以成爲解決方案,但後一部分......

    internal static Dictionary<string, Dictionary<string, object>> OperationDic(Dictionary<string, Dictionary<string, object>> a, Dictionary<string, Dictionary<string, object>> b, string operation)` 
        { 
         switch (operation) 
         { 
          case "+": 
           var result = a.Concat(b).GroupBy(d => d.Key).ToDictionary (d => d.Key, d => d.First().Value); 
           return result;    
          default: 
    
           throw new Exception("Fail ..."); 
         }    
        } 
    
+0

已經我堅持,我試圖做任何事,我還在找 – 2013-02-13 10:42:56

+0

請告訴我們您嘗試過,所以我們可以在其上展開的。 – 2013-02-13 10:43:59

+0

我改變了我的要求 – 2013-02-13 11:01:43

回答

0

試試這個

VAR的結果= a.Concat(B).GroupBy(C => c.Key).ToDictionary>(

+1

失敗...... ........... – 2013-02-13 11:19:15

+1

這個答案是不完整的...... – leppie 2013-02-13 11:19:52

1

這不是對我很清楚你想要什麼。這種嘗試將兩個庫合併:

// first copy everything from a 
    var result = new Dictionary<string, Dictionary<string, object>>(a); 

    // now check to see if we can add stuff from b 
    foreach (var entryOuter in b) 
    { 
     Dictionary<string, object> existingValue; 
     if (result.TryGetValue(entryOuter.Key, out existingValue)) 
     { 
     // there's already an entry, see if we can add to it 
     foreach (var entryInner in entryOuter.Value) 
     { 
      if (existingValue.ContainsKey(entryInner.Key)) 
      throw new Exception("How can I merge two objects? Giving up."); 
      existingValue.Add(entryInner.Key, entryInner.Value); 
     } 
     } 
     else 
     { 
     // new entry 
     result.Add(entryOuter.Key, entryOuter.Value); 
     } 
    } 

    return result; 

您可能要添加檢查nulla,bexistingValue(當它存在時)可以是null

+0

'拋出新的異常(「我怎樣才能合併兩個對象?放棄。」) - 不錯的嘗試,我認爲這正是什麼被問到這裏。 – pescolino 2013-02-13 12:11:05

+0

@pescolino如果「a」的「外部」鍵與「b」的「外部」鍵相同,則兩個對應的值是字典。正如你看到我合併它們。但是,當這兩個字典共享一個「內部」鍵時,內部值是「object」類型。沒有辦法合併兩個一般對象。爲此,需要額外的東西,例如將'object'類型改爲一個新的'IMergeable'類型,其中'IMergeable'接口應該提供一個與另一個對象合併的方法。 – 2013-02-13 12:39:12

+0

這可能是我的請求的解決方案,但我正在尋找一種解決方案,而不是隻是linq – 2013-02-13 12:48:41

0
internal static Dictionary<string, Dictionary<string, object>> OperationDic(Dictionary<string, Dictionary<string, object>> a, Dictionary<string, Dictionary<string, object>> b, string operation) 
    { 
     var result = new Dictionary<string, Dictionary<string, object>>(a); 
     switch (operation) 
     { 
      case "+":     
      // now check to see if we can add stuff from b 
      foreach (var entryOuter in b) 
      { 
       Dictionary<string, object> existingValue; 
       if (result.TryGetValue(entryOuter.Key, out existingValue)) 
       { 
        Dictionary<string, object> Value = entryOuter.Value; 
        result[entryOuter.Key] = existingValue.Concat(Value).GroupBy(d => d.Key).ToDictionary(d => d.Key, d => d.First().Value); 
       } 
       else 
       { 
       // new entry 
       result.Add(entryOuter.Key, entryOuter.Value); 
       } 
      } 
      return result; 
      default:      
       throw new Exception("FAIL ..."); 
     } 
    } 
0

你應該問自己的第一個問題:合併兩個字典的結果有哪些類型?如果價值共享相同的密鑰,價值如何合併在一起?

這可能是這樣的:

public static Dictionary<TKey, IEnumerable<TValue>> Merge<TKey, TValue>(this IDictionary<TKey, TValue> this_, IDictionary<TKey, TValue> other) 
{ 
    return this_.Concat(other).  // IEnumerable<KeyValuePair<TKey, TValue>> 
     GroupBy(kvp => kvp.Key). // grouped by the keys 
     ToDictionary(grp => grp.Key, grp => grp.Select(kvp => kvp.Value).Distinct()); 
} 

所以你Dictionary<string, Dictionary<string, object>>型的兩個庫會去Dictionary<string, IEnumerable<Dictionary<string, object>>>

然而,你的價值觀是字典,所以你可能想將它們合併:

public static Dictionary<TKey, IEnumerable<TValue>> Flatten<TKey, TValue>(IEnumerable<Dictionary<TKey, TValue>> dictionaries) 
{ 
    return dictionaries.SelectMany(d => d.Keys).Distinct().   // IEnumerable<TKey> containing all the keys 
     ToDictionary(key => key, 
      key => dictionaries.Where(d => d.ContainsKey(key)).  // find Dictionaries that contain the key 
       Select(d => d.First(kvp => kvp.Key.Equals(key))). // select that key (KeyValuePair<TKey, TValue>) 
       Select(kvp => kvp.Value));       // and the value 
} 

這需要一個IEnumerable<Dictionary<string, object>>並將其轉換爲一個Dictionary<string, IEnumerable<object>>。您現在可以針對Merge生成的每個字典值調用此方法。

的呼聲是:

Dictionary<string, IEnumerable<Dictionary<string, object>>> result1 = dic1.Merge(dic2); 
Dictionary<string, Dictionary<string, IEnumerable<object>>> result2 = dic1.Merge(dic2).ToDictionary(kvp => kvp.Key, kvp => Flatten(kvp.Value)); 
相關問題