2017-02-22 48 views
0
class Key { string s; int i; } 

給定一個Dictionary<Key,int>我想要一個新的Dictionary<string,int>這是所有密鑰每個Key.s最小字典值的映射。LINQ的總字典到新的字典

我覺得這應該很容易,但我無法得到它。

感謝

澄清:

var dict = new Dictionary<Key,int>(); 
dict.Add(new Key("a", 123), 19); 
dict.Add(new Key("a", 456), 12); 
dict.Add(new Key("a", 789), 13); 
dict.Add(new Key("b", 998), 99); 
dict.Add(new Key("b", 999), 11); 

,我想產生詞典:

"a" -> 12 
"b" -> 11 

希望幫助。

+3

這不是我清楚你的意思是「最小的字典值對每個鍵入所有鍵「。具有樣本輸入和期望輸出數據的[mcve]比現有形式的問題更有幫助。 –

+0

@JonSkeet問題已更新。 – CoderBrien

+0

所以你想按鍵的's'屬性來組合原始字典的條目,然後在每個組中你只對字典值最小的條目感興趣;那麼從所有剩餘的字典條目中,您將創建一個新的字典,其中的密鑰是原始密鑰的「s」屬性,並且該值是原始值? – stakx

回答

3

我不清楚在什麼你想這樣做,但你可以從一個字典到另一個做的映射與.Select(...和/或.ToDictionary(...

例如:

Dictionary<Key, int> original = ... 
Dictionary<string, int> mapped = original.ToDictionary((kvp) => kvp.Key.s, (kvp) => kvp.Key.i); 

如果你改善你的問題更清楚,我會改進我的答案。

編輯:(問題澄清)

var d = dict.GroupBy(kvp => kvp.Key.s).ToDictionary(g => g.Key, g => g.Min(k => k.Value)); 

您可以通過按鍵s財產要組,然後選擇最小的字典值作爲新字典的價值。

+0

@caesay問題已更新。 – CoderBrien

+0

@caesay我需要每個kvp.Key.s的miniumum kvp.Value – CoderBrien

+0

@CoderBrien:你去了! – caesay

1

一個跳過由.GroupBy創建Lookup更通用的方法:

public static Dictionary<K, V> aggregateBy<T, K, V>(
     this IEnumerable<T> source, 
     Func<T, K> keySelector, 
     Func<T, V> valueSelector, 
     Func<V, V, V> aggregate, 
     int capacity = 0, 
     IEqualityComparer<K> comparer = null) 
    { 
     var dict = new Dictionary<K, V>(capacity, comparer); 
     foreach (var t in source) 
     { 
      K key = keySelector(t); 
      V accumulator, value = valueSelector(t); 
      if (dict.TryGetValue(key, out accumulator)) 
       value = aggregate(accumulator, value); 
      dict[key] = value; 
     } 
     return dict; 
    } 

使用示例:

var dict = new Dictionary<Tuple<string,int>, int>(); 
    dict.Add(Tuple.Create("a", 123), 19); 
    dict.Add(Tuple.Create("a", 456), 12); 
    dict.Add(Tuple.Create("a", 789), 13); 
    dict.Add(Tuple.Create("b", 998), 99); 
    dict.Add(Tuple.Create("b", 999), 11); 

    var d = dict.aggregateBy(p => p.Key.Item1, p => p.Value, Math.Min); 

    Debug.Print(string.Join(", ", d));  // "[a, 12], [b, 11]" 
+0

我不認爲我需要它在這種情況下,但感謝指出效率低下! – CoderBrien