Thursday, April 28, 2011

Comparing Arrays in C#

I am trying to compare two arrays with eachother. I tried this code and got the following errors

static bool ArraysEqual(Array a1, Array a2)
{
    if (a1 == a2)
        return true;

    if (a1 == null || a2 == null)
        return false;

    if (a1.Length != a2.Length)
        return false;

    IList list1 = a1, list2 = a2; //error CS0305: Using the generic type 'System.Collections.Generic.IList<T>' requires '1' type arguments
    for (int i = 0; i < a1.Length; i++)
    {
        if (!Object.Equals(list1[i], list2[i])) //error CS0021: Cannot apply indexing with [] to an expression of type 'IList'(x2)
            return false;
    }
    return true;
}

Why do i get that error? i went for a low tech solution and did this which works fine but i need to copy/paste it several times for each type.

static bool ArraysEqual(byte[] a1, byte[] a2)
{
    if (a1 == a2)
        return true;

    if (a1 == null || a2 == null)
        return false;

    if (a1.Length != a2.Length)
        return false;

    for (int i = 0; i < a1.Length; i++)
    {
        if (a1[i] != a2[i])
            return false;
    }
    return true;
}
From stackoverflow
  • I think IList has to be specified like this:

    IList<string> list1 = a1, list2 = a2;
    
  • "Why do i get that error?" - probably, you don't have "using System.Collections;" at the top of the file - only "using System.Collections.Generic;" - however, generics are probably safer - see below:

    static bool ArraysEqual<T>(T[] a1, T[] a2)
    {
        if (ReferenceEquals(a1,a2))
            return true;
    
        if (a1 == null || a2 == null)
            return false;
    
        if (a1.Length != a2.Length)
            return false;
    
        EqualityComparer<T> comparer = EqualityComparer<T>.Default;
        for (int i = 0; i < a1.Length; i++)
        {
            if (!comparer.Equals(a1[i], a2[i])) return false;
        }
        return true;
    }
    
    acidzombie24 : Thank you for the 2nd time today Marc :D
  • Providing that you have LINQ available and don't care too much about performance, the easiest thing is the following:

    var arraysAreEqual = Enumerable.SequenceEquals(a1, a2);
    
    Joel Mueller : Or just a1.SequenceEquals(a2). What leads you to believe this would perform any worse than the accepted answer?
    Joel Mueller : I suppose the enumerable version can't rely on comparing lengths, so the accepted answer would be faster in cases where the arrays being compared were of different lengths.
    Noldorin : @Joel: That's essentially the reason. The SequenceEquals method uses enumerators, which means instantiating an iterator and then making numerous function calls to loop through it, all adding overhead. Normally I wouldn't think twice about using this method - it was just a small caveat.

0 comments:

Post a Comment