Tatham Oddie

Comparing arrays in C#

with 20 comments

Use the SequenceEqual extension method in LINQ.

For example:

var array1 = new byte[] { 1, 2, 3, 4 };
var array2 = new byte[] { 1, 2, 3, 4 };

var areEqual = array1.SequenceEqual(array2); //returns true

Written by Tatham Oddie

July 1, 2008 at 15:08

20 Responses

Subscribe to comments with RSS.

  1. Totally silly … I’ve run into all kinds of silly things like that, especially with their data structures. MS needs to sweat the details more on stuff like this, and worry a little less about all the frameworks built on this stuff.

    kindageeky

    July 2, 2008 at 04:22

  2. What on earth ever happened to memcmp ?

    radsdau

    July 7, 2008 at 10:26

  3. What if you compare the hashcode? that would be an ideal comparison, no?

    Like NoOther

    July 18, 2008 at 01:05

  4. Hi LikeNoOther,

    Nice idea, but unfortunately they didn’t override the GetHashCode method in the array class. The default Object.GetHashCode implementation will be used instead which returns the sync block index of the object instance. Net effect will be the same as doing Object.Equals – different instances will not be considered equal even if they contain the same data.

    Good try though. :)

    Tatham

    Tatham Oddie

    July 18, 2008 at 09:15

  5. 1- I agree with MS designers not overriding Array.Equals as it’s supposed to provide “value-like” behaviour. As a design best practice we should be consistent around == and != operators and also overriding Object.Equals method. BUT, I do 100% agree framework is missing something like Array.CompareContent!

    2- “memcpy” is already being used internally by System.Buffer. and perhaps MS folks would use “memcmp” internally easing Array.CompareContent implementation, BUT exposing such methods has issues with OO paradigm IMO, and higher level approaches are okay with almost same performance.

    3- as Taham said hash-value comparison won’t help work as Array doesn’t implement content-based hash generation. however, not a good idea generating hash-value in the sake of content comparison – performance issues in particular.

    Well, don’t understand why MS guys haven’t added such a helper method since even the very first version! :(

    Jamal Mavadat

    July 22, 2008 at 03:10

  6. From System.Linq:

    Enumerable.SequenceEqual();

    or

    Console.WriteLine(new byte[] {1,2,3}.SequenceEqual(new byte[] {1,2,3}));

    RichB

    November 4, 2008 at 23:23

  7. Great tip Richard! I’ll add it to the post.

    Tatham Oddie

    November 5, 2008 at 08:12

  8. If you are not using Linq
    Pleas try

    Convert.ToBase64String(array1)==Convert.ToBase64String(array2)

    jojan

    January 30, 2009 at 04:05

  9. There are two things wrong with your method:

    1. You can’t have both static and override modifiers on the same method – I presume this was a typo;

    2. Your method only works for vectors; multi-dimensional arrays would take a lot more effort.

    Richard

    February 24, 2009 at 06:24

  10. Hi,
    This technique is gud for me to compare to byte[] arrays.

    Convert.ToBase64String(array1)==Convert.ToBase64String(array2)

    Thanks!!

    Hemant Kumar

    April 15, 2009 at 15:02

  11. Microsoft is correct in their explanation. I think as you become more experienced with OO languages it will make more sense.

    However, I wanted to explain why some of the suggestions here should not be used.

    1: Convert.ToBase64String(array1)==Convert.ToBase64String(array2)
    The problems with this are as follows:
    a: You are always getting the worst possible performance out of this. Without first checking the lengths of the arrays to be sure they are equal then you will always end up processing both arrays entirely.
    b: Terrible runtime performance. You are iterating across all of array1 and array2 to convert them to strings, then iterating across both resulting strings to check equality. This will do twice as much work as just iterating through them and comparing the array byte values. Just because a method is provided by the runtime does not make it any faster than doing it manually(in most cases).
    c: Terrible memory use. Although the strings are only used for a moment, there is a price to pay for allocating them.

    I would write more but now I am tired of all of this.
    -Tim

    Tim

    July 3, 2009 at 10:18

  12. If you don’t want to create your own class, just use this helper method somewhere.

    private static bool CompareByteArrays(byte[] array1, byte[] array2)
    {
    if (array1.Length != array2.Length)
    return false;

    for (int i = 0; i < array1.Length; i++)
    if (array1[i] != array2[i])
    return false;

    return true;
    }

    Good luck!

    =D Kees

    Kees C. Bakker

    August 11, 2009 at 19:15

  13. public static bool ValueCompare(this T[] a, T[] b) where T: struct
    {
       if (a.Length != b.Length)
          return false;
       EqualityComparer q = EqualityComparer.Default;
       for (int i = 0; i < a.Length; i++)
          if (!q.Equals(a[i],b[i]))
             return false;
       return true;
    }

    Glenn Slayden

    August 20, 2009 at 15:14

    • The angle brackets for the generic argument T were stripped off my posting by your blog. It belongs after the function name “ValueCompare” and also after the EqualityComparer.

      Glenn Slayden

      August 20, 2009 at 15:18

  14. [...] fourni la solution propre recherchée avec c# 3.5 : http://blog.tatham.oddie.com.au/2008/07/01/comparing-byte-arrays-in-c-or-at-least-trying-to/ Publié dans General | Commentaires [...]

  15. [...] 2. Vergelijken van byte arrays oplossing [...]

  16. ///
    /// Checks the equality of two arrays
    ///
    /// True if equals otherwise False
    public static bool Equals(this T[] array, T[] other)
    {
    if(array == null && other == null) return true;
    if(array == null || other == null)return false;
    if(array.Length != other.Length) return false;

    return !array.Where((t, i) => !Equals(t, other[i])).Any();
    }

    etil

    February 6, 2011 at 01:07

  17. If you loop, you might as well loop in parallel.

    public static bool CompareArrays(T[] arrayA, T[] arrayB)
    {
    if (arrayA == arrayB) return true;
    if (arrayA == null || arrayB == null) return false;
    if (arrayA.Length != arrayB.Length) return false;

    var worked = Parallel.For(0, arrayA.Length, (i, loopState) =>
    {
    T itemA;
    //use the short circuit to set the item in the first part of the if, and compare in the second.
    if ((itemA = arrayA[i]) == null || !itemA.Equals(arrayB[i]))
    loopState.Stop();
    });

    //if successfully completed, then its correct. If broken out before the end, that means something wasnt right.
    return worked.IsCompleted;
    }

    Vlad

    May 1, 2011 at 17:02

  18. I am sure you will love at my estore for less

    itexybelia

    December 11, 2011 at 21:43


Leave a Reply

Fill in your details below or click an icon to log in:

Gravatar
WordPress.com Logo

Please log in to WordPress.com to post a comment to your blog.

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.