我正在努力解决一些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
答案 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
中的原始条目...