views:

172

answers:

4

Hi, I am using dictionary for storing ID,otherID and bool value. Unfortunately it compares array reference, therefore I cannot use it. Is there any way how to have an array as key but compare its values instead of reference? Thanks

+4  A: 

You can use the Comparer property of the dictionary to set it to a custom comparer created by you.

EDIT: actually the property is read-only, sorry. You should definitely use the proper constructor:

class IntArrayComparer : IEqualityComparer<int[]> {
    public bool Equals(int[] x, int[] y) {
        if (x.Length != y.Length) {
            return false;
        }
        for (int i = 0; i < x.Length; ++i) {
            if (x[i] != y[i]) {
                return false;
            }
        }
        return true;
    }
    public int GetHashCode(int[] obj) {
        int ret = 0;
        for (int i = 0; i < obj.Length; ++i) {
            ret ^= obj[i].GetHashCode();
        }
        return ret;
    }
}
static void Main(string[] args) {
    Dictionary<int[], bool> dict = new Dictionary<int[], bool>(new IntArrayComparer());
}
Paolo Tedesco
+3  A: 

You can try implementing IEqualityComparer<int[]> and then pass an instance of it to the proper constructor.

Darin Dimitrov
+2  A: 

There are basically two ways of doing that:

  • Create a comparer that implements IEqualityComparable<int[]>, that you pass to the constructor of the dictionary.
  • Create a key class that encapsulates the integer array and implements IEquatable<T>.
Guffa
A: 

There's nothing wrong with orsogufo's answer, but I wanted to point out that if you have .NET 3.5, you can implement an ArrayValueComparer with a lot less code, and at the same time make it generic, so it can compare the values of any type of array, and not just integer arrays. For that matter, you could easily make it work with any IEnumerable, and not just arrays.

using System.Collections.Generic;
using System.Linq;

class ArrayValueComparer<T> : IEqualityComparer<T[]>
{
    public bool Equals(T[] x, T[] y)
    {
        return x.SequenceEqual(y, EqualityComparer<T>.Default);
    }

    public int GetHashCode(T[] obj)
    {
        return obj.Aggregate(0, (total, next) => total ^ next.GetHashCode());
    }
}

static void Main(string[] args)
{
    var dict = new Dictionary<int[], bool>(new ArrayValueComparer<int>());
}
Joel Mueller