在Java中,arrays .equals()允许轻松地比较两个基本数组的内容(重载可用于所有基本类型)。

c#中有这样的东西吗?在c#中是否存在比较两个数组内容的“神奇”方法?


当前回答

对于。net 4.0及更高版本,您可以通过使用structuralcompare类型比较数组或元组中的元素:

object[] a1 = { "string", 123, true };
object[] a2 = { "string", 123, true };

Console.WriteLine (a1 == a2);        // False (because arrays is reference types)
Console.WriteLine (a1.Equals (a2));  // False (because arrays is reference types)

IStructuralEquatable se1 = a1;
//Next returns True
Console.WriteLine (se1.Equals (a2, StructuralComparisons.StructuralEqualityComparer)); 

其他回答

可列举的使用。LINQ中的SequenceEqual。

int[] arr1 = new int[] { 1,2,3};
int[] arr2 = new int[] { 3,2,1 };

Console.WriteLine(arr1.SequenceEqual(arr2)); // false
Console.WriteLine(arr1.Reverse().SequenceEqual(arr2)); // true

对于。net 4.0及更高版本,您可以通过使用structuralcompare类型比较数组或元组中的元素:

object[] a1 = { "string", 123, true };
object[] a2 = { "string", 123, true };

Console.WriteLine (a1 == a2);        // False (because arrays is reference types)
Console.WriteLine (a1.Equals (a2));  // False (because arrays is reference types)

IStructuralEquatable se1 = a1;
//Next returns True
Console.WriteLine (se1.Equals (a2, StructuralComparisons.StructuralEqualityComparer)); 

对于某些应用可能更好:

string.Join(",", arr1) == string.Join(",", arr2)
        int[] a = { 2, 1, 3, 4, 5, 2 };

        int[] b = { 2, 1, 3, 4, 5, 2 };

        bool ans = true;

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

        string str = "";

        if(ans == true)
        {
            str = "Two Arrays are Equal";
        }

        if (ans == false)
        {
            str = "Two Arrays are not Equal";
        }

       //--------------Or You can write One line of Code-------------

        var ArrayEquals = a.SequenceEqual(b);   // returns true

如果您不想比较顺序,但确实想比较每一项的计数,包括处理空值,那么我为此编写了一个扩展方法。

例如,它给出了以下结果:

new int?[]{  }.IgnoreOrderComparison(new int?{ });                            // true
new int?[]{ 1 }.IgnoreOrderComparison(new int?{ });                           // false
new int?[]{ }.IgnoreOrderComparison(new int?{ 1 });                           // false
new int?[]{ 1 }.IgnoreOrderComparison(new int?{ 1 });                         // true
new int?[]{ 1, 2 }.IgnoreOrderComparison(new int?{ 2, 1 });                   // true
new int?[]{ 1, 2, null }.IgnoreOrderComparison(new int?{ 2, 1 });             // false
new int?[]{ 1, 2, null }.IgnoreOrderComparison(new int?{ null, 2, 1 });       // true
new int?[]{ 1, 2, null, null }.IgnoreOrderComparison(new int?{ null, 2, 1 }); // false
new int?[]{ 2 }.IgnoreOrderComparison(new int?{ 2, 2 });                      // false
new int?[]{ 2, 2 }.IgnoreOrderComparison(new int?{ 2, 2 });                   // true

代码如下:

public static class ArrayComparisonExtensions
{
    public static bool IgnoreOrderComparison<TSource>(this IEnumerable<TSource> first, IEnumerable<TSource> second) =>
        IgnoreOrderComparison(first, second, EqualityComparer<TSource>.Default);

    public static bool IgnoreOrderComparison<TSource>(this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
    {
        var a = ToDictionary(first, out var firstNullCount);
        var b = ToDictionary(second, out var secondNullCount);

        if (a.Count != b.Count)
            return false;

        if (firstNullCount != secondNullCount)
            return false;

        foreach (var item in a)
        {
            if (b.TryGetValue(item.Key, out var count) && item.Value == count)
                continue;
            return false;
        }


        return true;

        Dictionary<TSource, int> ToDictionary(IEnumerable<TSource> items, out int nullCount)
        {
            nullCount = 0;
            var result = new Dictionary<TSource, int>(comparer);
            foreach (var item in items)
            {
                if (item is null)
                    nullCount++;
                else if (result.TryGetValue(item, out var count))
                    result[item] = count + 1;
                else
                    result[item] = 1;
            }

            return result;
        }
    }
}

它只枚举每个枚举对象一次,但它确实为每个枚举对象创建了一个字典,并迭代这些字典一次。我对如何改善这一点很感兴趣。