如何通过减少一个或多个键并将多个记录(如果有)合并为一个来合并具有多个(三个)键的字典
本文关键字:合并 一个 三个 字典 何通过 如果 记录 | 更新日期: 2023-09-27 18:36:18
我有一个字典,定义
如下。
Dictionary<int[], int> D = new Dictionary<int[], int>();
其中键是一个 3 元素数组。我以这个为例来简化我的方案。(在我自己的代码中,键是一个复杂的类对象,其中包含 3-7 个元素的列表。
int[] key;
key = new int[] { 1, 1, 1 };
D.Add(key, 1);
key = new int[] { 1, 1, 2 };
D.Add(key, 2);
key = new int[] { 1, 1, 3 };
D.Add(key, 3);
key = new int[] { 1, 2, 4 };
D.Add(key, 4);
key = new int[] { 2, 1, 1 };
D.Add(key, 5);
key = new int[] { 2, 5, 1 };
D.Add(key, 6);
我想要的是有一种减少键数的方法,即,我想要一个 2 元素数组作为键,并将所有冗余值合并为一个值,以便生成的键值对应如下所示。(减少键的第一个索引)
{1 1, 6} //two instances of matching key of {1 1} resulted the value to have 1+5 =6
{1 2, 2}
{1 3, 3}
{2 4, 4}
{5 1, 6}
首先,您的字典可能无法按预期工作 - int[]
类型没有默认比较器,因此键在您的字典中不会是唯一的(例如,您可以有两个元素1 1 1
键)。要使其正常工作,您需要提供自定义IEqualityComparer<int[]>
。这也是使主要问题的解决方案起作用所必需的:
public class IntArrayEqualityComparer : IEqualityComparer<int[]>
{
public bool Equals(int[] x, int[] y)
{
if (x.Length != y.Length)
{
return false;
}
return x.Zip(y, (v1, v2) => v1 == v2).All(b => b);
}
public int GetHashCode(int[] x)
{
return 0;
}
}
因此,您应该按如下方式创建字典:
Dictionary<int[], int> D
= new Dictionary<int[], int>(new IntArrayEqualityComparer());
回到主要问题,以下是实现预期结果的方法:
var result = D
.GroupBy(
kvp => kvp.Key.Skip(1).ToArray(),
new IntArrayEqualityComparer())
.ToDictionary(
g => g.Key,
g => g.Sum(x => x.Value));