0

次の定義を持つ Dictionary があります。

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

私が欲しいのは、キーの数を減らす手段を持つことです。3 つの要素の配列を使用する代わりに、2 つの要素の配列をキーとして使用し、冗長なすべての値を 1 つの値に統合して、結果の KeyValue ペアが次のようになるようにします。(キーの最初のインデックスを減らす)

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

1 に答える 1

1

まず第一に、ディクショナリは期待どおりに機能しない可能性があります。int[]タイプのデフォルトの比較演算子がないため、キーはディクショナリ内で一意になりません (1 1 1たとえば、キーを持つ 2 つの要素を持つことができます)。これを機能させるには、 custom を提供する必要があります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));
于 2013-10-21T11:44:40.693 に答える