2012-05-01 28 views
1

我有一個通過連接TValueToString()方法,像這樣合併兩個或更多IDictionary<TKey, TValue>對象到一個IDictionary<TKey, string>一個幫手:合併IDictionary - 有沒有比這更高效的方法?

public class DictionaryHelper<TKey, TValue> 
{ 
    public static IDictionary<TKey, string> MergeDictionaries<TKey, TValue>(params IDictionary<TKey, TValue>[] dictionaries) where TValue : class 
    { 
     var returnValue = new Dictionary<TKey, string>(); 
     foreach (var dictionary in dictionaries) 
     { 
      foreach (var kvp in dictionary) 
      { 
       if (returnValue.ContainsKey(kvp.Key)) 
       { 
        returnValue[kvp.Key] += kvp.Value.ToString(); 
       } 
       else 
       { 
        returnValue[kvp.Key] = kvp.Value.ToString(); 
       } 
      } 
     } 
     return returnValue; 
    } 

} 

雖然這很簡單,很容易讀,好像應該有一個更有效的方法來做到這一點。在那兒?

+0

記住['kvp.Value'可以'null'。(HTTP:// MSDN .microsoft.com/en-us/library/k7z0zy8k.aspx)代碼行中有效的速度或效率? – user7116

+0

嗯...嗯,我的預期用法不應該允許,但我同意我需要處理該問題。感謝您指出了這一點。高效的表現......我不介意在前期做更多的努力。 –

+1

這可能會有所幫助:http://stackoverflow.com/questions/712927/how-to-add-2-dictionary-contents-without-looping-in-c-sharp –

回答

7

我不知道這是不是更有效,但至少它的要短得多:

var result = dictionaries.SelectMany(d => d) 
         .ToLookup(kvp => kvp.Key, kvp => kvp.Value) 
         .ToDictionary(g => g.Key, g => string.Concat(g)); 
+0

我會看看我能否寫出一個好的基準。 –

+0

@JeremyHolovacs:如果我們用你的作爲基線,他們都是平等的。 (*此評論的以前版本包括延遲字典創建在時間*) – user7116

+0

有趣。所以編譯器會或多或少地對待它們。然後它變成了可讀性。 –

0

您可以使用TryGetValue來混合源值的位置和檢索。

1

你可以刪除可見foreachSelectMany

foreach (var kvp in dictionaries.SelectMany(dd => dd)) 
{ 
    if (returnValue.ContainsKey(kvp.Key)) 
    { 
     returnValue[kvp.Key] += kvp.Value.ToString(); 
    } 
    else 
    { 
     returnValue[kvp.Key] = kvp.Value.ToString(); 
    } 
} 

而且你可以進一步擴展這種,although dtb's is more elegant and efficient

var merged = dictionaries.SelectMany(dd => dd) 
         .GroupBy(kvp => kvp.Key, kvp => kvp.Value) 
         .ToDictionary(
          gg => gg.Key, 
          gg => String.Concat(gg)); 

然而,這是不是可能是更有效或可讀比你目前的方法。

+0

你可以替換'.GroupBy(kvp => kvp.Key).ToDictionary(..)'與'.GroupBy(kvp => kvp.Key,kvp => kvp.Value).ToDictionary(g => g.Key,g => string.Concat(g)) '。所以它和我的答案完全一樣,除了GroupBy而不是ToLookup。我想知道哪個更有效...... – dtb

+0

謝謝,我的直覺說L2O不會有什麼區別,而ILSpy在L2O中使用'GroupBy'顯示的只是將一個調用推遲到'Lookup 。創建() ','ToLookup'立即使用。不知道有什麼區別,除了我正在做一個'Lookup'並且你已經擁有它了。 – user7116

相關問題