How to consolidate a Dictionary with multiple (three) keys by reducing one or more key and merging the multiple records (if any) into one single one?

只谈情不闲聊 提交于 2020-01-03 05:44:09

问题


I have a Dictionary with the following definition.

    Dictionary<int[], int> D = new Dictionary<int[], int>();

where the key is a 3 element array. I am giving this as example to simplify my scenario. (In my own code the Key is a complex class object that has a List of 3-7 elements in it for key.)

    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);

What i want is to have a means to reduce the number of keys, ie. instead of having an array of three element I want a 2 element array as key and have all the values that are redundant be consolidated into one single value so that the resulting KeyValue pairs should look the following way. (reducing the first index for keys)

    {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}

回答1:


First of all, your dictionary probably doesn't work as you expect - there is no default comparer for int[] type, so keys won't be unique in your dictionary (you can have two elements with 1 1 1 key for example). To get this to work you need to provide custom IEqualityComparer<int[]>. This will also be needed to make the solution to your main problem work:

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;
    }
}

So you should create your dictionary as follows:

Dictionary<int[], int> D
    = new Dictionary<int[], int>(new IntArrayEqualityComparer());

Returning to the main issue, here is how you can achieve the desired result:

var result = D
    .GroupBy(
        kvp => kvp.Key.Skip(1).ToArray(),
        new IntArrayEqualityComparer())
    .ToDictionary(
        g => g.Key,
        g => g.Sum(x => x.Value));


来源:https://stackoverflow.com/questions/19493122/how-to-consolidate-a-dictionary-with-multiple-three-keys-by-reducing-one-or-mo

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!