Linq将数据汇总到两个词典中

时间:2013-10-29 19:10:28

标签: c# linq

我正在努力解决一些linq以实现以下目标:

Dict1
1     0
2     0
3     1
4     1
5     2
6     2
7     2

Dict2

1     45
2     30
3     31
4     43
5     20
6     10
7     5

我想根据字典1中的匹配键对字典2中的值求和,并返回max或任何默认键,结果汇总,不包括dict 1中的值为0。

例如:

New Dict
1    45
2    30
4    74
7    35

3 个答案:

答案 0 :(得分:1)

听起来你有效地按照字典1中的值进行分组。我怀疑你想要某些东西

var sums = from p1 in dict1
             where p1.Value != 0
             join p2 in dict2 on p1.Key equals p2.Key
             group p2 by p1.Value into g
             select new { Key = g.Max(p2 => p2.Key),
                          Sum = g.Sum(p2 => p2.Value) };

结果如下:

4 74
7 35

但它不包括您的{1,45}或{2,30}结果。我以为你想忽略第一个字典中值为0的条目?

答案 1 :(得分:1)

因此,您希望从第一个字典中获取值不为零的所有对,按字典值对它们进行分组,然后对于每个组,它将表示新字典中的一个条目。该条目的关键是组中的最大键,该值是该键的第二个字典中值的总和。

然后只需将零值添加到Concat的末尾,并将其放入字典中:

var newDict = dict1.Where(pair => pair.Value != 0)
        .GroupBy(pair => pair.Value)
        .Select(group => new KeyValuePair<int, int>(
            group.Max(pair => pair.Key),
            group.Where(pair => dict2.ContainsKey(pair.Key))
                .Sum(pair => dict2[pair.Key])))
        .Concat(dict1.Where(pair => pair.Value == 0))
        .ToDictionary(pair => pair.Key, pair => pair.Value);

答案 2 :(得分:0)

我想将此答案添加为参考。我不明白为什么其他答案从dict1开始?当我们从dict2这样开始时,它会更加方便和轻松:

var result = dict2.GroupBy(x => dict1[x.Key] == 0 ? dict1.Min(a=>a.Value) - x.Key :
                                                              dict1[x.Key])
                  .ToDictionary(g => g.Max(x=>x.Key), g => g.Sum(x => x.Value));

或者如果您不关心1-line LINQ solution,只需声明一些保持最小值dict1的变量(这当然会有更好的表现):

var min = dict1.Min(a=>a.Value);
var result = dict2.GroupBy(x => {
                     var d = dict1[x.Key];
                     return d == 0 ? min - Math.Abs(x.Key) : d;
                  }).ToDictionary(g => g.Max(x=>x.Key), g => g.Sum(x => x.Value));

注意:上面的代码可以在某些有限的条件下工作,它不会检查key existence,因为它假设2个dicts具有相同的密钥集合(或至少{{1}中的所有密钥可以在dict2中找到{1}}。如果dict1中的条目与dict2中的任何键都不匹配,我们需要更多规则来处理此案例,例如keep dict1中的原始条目...