Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to compare arrays in C#? [duplicate]

Tags:

arrays

c#

compare

People also ask

How do you compare two arrays the same?

The Arrays. equals() method checks the equality of the two arrays in terms of size, data, and order of elements. This method will accept the two arrays which need to be compared, and it returns the boolean result true if both the arrays are equal and false if the arrays are not equal.

Can we compare two character arrays in C?

From the documentation on strcmp: Compares the C string str1 to the C string str2. This function starts comparing the first character of each string. If they are equal to each other, it continues with the following pairs until the characters differ or until a terminating null-character is reached.


You can use the Enumerable.SequenceEqual() in the System.Linq to compare the contents in the array

bool isEqual = Enumerable.SequenceEqual(target1, target2);

You're comparing the object references, and they are not the same. You need to compare the array contents.

.NET2 solution

An option is iterating through the array elements and call Equals() for each element. Remember that you need to override the Equals() method for the array elements, if they are not the same object reference.

An alternative is using this generic method to compare two generic arrays:

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;

    var comparer = EqualityComparer<T>.Default;
    for (int i = 0; i < a1.Length; i++)
    {
        if (!comparer.Equals(a1[i], a2[i])) return false;
    }
    return true;
}

.NET 3.5 or higher solution

Or use SequenceEqual if Linq is available for you (.NET Framework >= 3.5)


There is no static Equals method in the Array class, so what you are using is actually Object.Equals, which determines if the two object references point to the same object.

If you want to check if the arrays contains the same items in the same order, you can use the SequenceEquals extension method:

childe1.SequenceEqual(grandFatherNode)

Edit:

To use SequenceEquals with multidimensional arrays, you can use an extension to enumerate them. Here is an extension to enumerate a two dimensional array:

public static IEnumerable<T> Flatten<T>(this T[,] items) {
  for (int i = 0; i < items.GetLength(0); i++)
    for (int j = 0; j < items.GetLength(1); j++)
      yield return items[i, j];
}

Usage:

childe1.Flatten().SequenceEqual(grandFatherNode.Flatten())

If your array has more dimensions than two, you would need an extension that supports that number of dimensions. If the number of dimensions varies, you would need a bit more complex code to loop a variable number of dimensions.

You would of course first make sure that the number of dimensions and the size of the dimensions of the arrays match, before comparing the contents of the arrays.

Edit 2:

Turns out that you can use the OfType<T> method to flatten an array, as RobertS pointed out. Naturally that only works if all the items can actually be cast to the same type, but that is usually the case if you can compare them anyway. Example:

childe1.OfType<Person>().SequenceEqual(grandFatherNode.OfType<Person>())

Array.Equals is comparing the references, not their contents:

Currently, when you compare two arrays with the = operator, we are really using the System.Object's = operator, which only compares the instances. (i.e. this uses reference equality, so it will only be true if both arrays points to the exact same instance)

Source

If you want to compare the contents of the arrays you need to loop though the arrays and compare the elements.

The same blog post has examples of how to do this. The basic implementation is:

public static bool ArrayEquals<T>(T[] a, T[] b)
{
    if (a.Length != b.Length)
    {
        return false;
    }

    for (int i = 0; i < a.Length; i++)
    {
        if (!a[i].Equals(b[i]))
        {
            return false;
        }
    }

    return true;
}

Though this will have performance issues. Adding a constraint:

public static bool ArrayEquals<T>(T[] a, T[] b) where T: IEquatable<T>

will improve things but will mean the code only works with types that implement IEquatable.

Using EqualityComparer.Default's Equal method instead of calling Equals on the types themselves will also improve performance without requiring the type to implement IEquatable. In this case the body of the method becomes:

    EqualityComparer<T> comparer = EqualityComparer<T>.Default;

    for (int i = 0; i < a.Length; i++)
    {
        if (!comparer.Equals(a[i], b[i]))
        {
            return false;
        }
    }

The Equals method does a reference comparison - if the arrays are different objects, this will indeed return false.

To check if the arrays contain identical values (and in the same order), you will need to iterate over them and test equality on each.