Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Linq跨两个字典聚合数据_C#_Linq - Fatal编程技术网

C# Linq跨两个字典聚合数据

C# Linq跨两个字典聚合数据,c#,linq,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 我想根据dictionary 1中的匹配键对dictionary 2中的值求和,并返回max或任何默认键,结果汇总为0,不包括dict 1中的值 例如: 听起来好像是在按字典1中的值进行

我正在与一些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
我想根据dictionary 1中的匹配键对dictionary 2中的值求和,并返回max或任何默认键,结果汇总为0,不包括dict 1中的值

例如:


听起来好像是在按字典1中的值进行有效分组。我猜你想要的是:

其结果如下:

4 74
7 35

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

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

然后用
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);
var newDict=dict1.Where(pair=>pair.Value!=0)
.GroupBy(pair=>pair.Value)
.选择(组=>new KeyValuePair(
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);

我想添加此答案作为参考。我不明白为什么其他答案是从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解决方案
,只需声明一些保持
dict1
最小值的变量即可(这种方式当然具有更好的性能):


注意:上面的代码可以在某些有限的条件下工作,它不检查
键的存在
,因为它假设两个dict具有相同的键集合(或者至少可以在
dict1
中找到
dict2
中的所有键。如果
dict2
中有一个条目与
dict1
中的任何键都不匹配,我们需要更多的规则来处理这种情况,例如在
dict2
中保留原始条目。

您的要求不清楚。为什么结果中缺少3、5和6s?我想在原始字典中的值不在0的情况下,将这些结果聚合为默认键。因此,firstordefault、max等@PMOrion仍然不清楚,似乎用词来表达并不容易。@PMOrion:啊,我想我明白你的意思,但不是很清楚。如果你排除字典中的值,我会尝试添加一个答案结果如果Dict1值为0,那么为什么结果中的值为1和2。看起来您的结果应该包含键3、4、5、6和7看起来这还需要1个
合并步骤
来包含
值为
零的原始条目?@KingKing-Right,谢谢,添加了。1)为什么要获取一个keyvalueapiar,从中获取密钥,然后查找该密钥的值?只需从该对中获取值。您可以在
GroupBy
中执行两次此操作。2)为什么要计算
min
?如果为0,则程序工作,如果不是,则不工作。只需使用
0
而不是
min
。3) 这不支持键的负整数,但不确定这是否是真正的问题。4) 你不能处理一个字典有值而另一个没有值的情况。@Servy good point on the 4),对于2)我不同意,如果按
0进行分组,我们将只有一组2个条目(1和2),而目的是我们需要两组,一组用于键1,另一组用于键2。嗯,你指出了一些相当大的问题。不过,我认为做一些修改会更好,如果不想说它很快的话,字典中的
查找也不是很糟糕。我用OP的样本输入测试了这段代码。计算
min
甚至
max
的目的是为了找到一种方法,如果(dict1的)条目的值为
0
但不需要计算min,就可以得到
groupby
的不同值,您可以只使用零,让所有负组键都是零组的键,所有正组键都是非零组的键。如果您这样做的话,您就不能在第二个字典中支持负数键(由于不同的原因,您无论如何也不能支持负数键)。总而言之,你只是想变得太聪明。它使代码更难理解,更难调试,并且在代码中引入了一些小错误。只需添加额外的几行代码,在需求读取时将其写出来即可。基本上,除非有一个int范围没有一个键可以在其中,否则它无法工作。如果您知道没有负数键,那么只需对数字求反,如果您*无法做出该断言,那么您需要进行更根本的更改,以确保在字典值为零的情况下,对象始终是不同的。
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);
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));
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));