Comparing Two Arrays

I was looking at some old code today that was checking if two byte arrays had the same data in them.  It was a simple loop that compared each element.  I recalled my blog post from November of last year about comparing collections/arrays in MSTest and thought, "I wonder if LINQ has something similar"?

As a matter of fact it does!  IEnumerable<T>.SequenceEqual() does exactly what I was looking for.  By default, it uses the type's default comparer, or you can supply your own.  Very nice!

Technorati Tags: ,

6 Comments

  • Yes, but if the arrays are of different lengths, the LINQ method is not efficient, because it could compare a lot of elements before finding out the final result.

  • Lucian,

    The implementation of SequenceEqual stops as soon as it finds an element that is not equal. It doesn't go all the way to the end before returning a result.

  • Yes, but consider that I want to compare [1-10000] and [1-10001], the worst case. U need 10000 comparisons only to find out that the arrays are different. So it's best first to check the lengths and then call SequenceEqual.

  • But if you have two arrays of different lengths where the first few thousand elements are equal, SequenceEqual will compare each element until it finds one that isn't equal, rather than checking the length first.

    Some Linq method (eg: Count, ElementAt) will use the generic ICollection or IList interface as a shortcut, but the SequenceEqual method doesn't. However, it's not hard to come up with a workaround:

    private static int? ListCount(IEnumerable source)
    {
    var collection = source as ICollection;
    if (null != collection) return collection.Count;

    var collection2 = source as ICollection;
    if (null != collection2) return collection2.Count;

    return null;
    }

    public static bool SequenceEqualEx(this IEnumerable first, IEnumerable second, IEqualityComparer comparer)
    {
    int? firstCount = ListCount(first);
    int? secondCount = ListCount(second);
    if (null != firstCount && null != secondCount && firstCount != secondCount) return false;
    return first.SequenceEqual(second, comparer);
    }

  • Yes, that's exactly my point.

  • Lucian/RichardD,

    Enumerator.SequenceEquals is designed to compare *any* IEnumerable -- not just arrays. You can't make the assumption that obtaining the Count is a quick operation. Since obtaining the Count *may* require enumerating the entire collection, simply looking at Count itself could be a very expensive operation.

    If you're *only* concerned with comparing simple byte[] or int[], I would agree that checking the count first could be more efficient. But for a general, all-purpose, performant check, SequenceEquals will be fine.

Comments have been disabled for this content.