2017-02-22 80 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