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

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


当前回答

        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

其他回答

也可以使用array1.ToList()。All(x => array2.Contains(x))如果您需要比较顺序不相同的数组

SequenceEqual只在满足两个条件时才返回true。

它们包含相同的元素。 元素的顺序是一样的。

如果您只想检查它们是否包含相同的元素,而不管它们的顺序如何,那么您的问题属于

values2是否包含values1中包含的所有值?

可以使用LINQ扩展方法Enumerable。Except,然后检查结果是否有任何值。这里有一个例子

int[] values1 = { 1, 2, 3, 4 };
int[] values2 = { 1, 2, 5 };
var result = values1.Except(values2);
if(result.Count()==0)
{
   //They are the same
}
else
{
    //They are different
}

通过这个你也可以自动得到不同的项目。一石二鸟。

请记住,如果像这样执行代码

var result = values2.Except(values1);

你会得到不同的结果。

在我的例子中,我有一个数组的本地副本,想要检查是否有任何东西已经从原始数组中删除,所以我使用这个方法。

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

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

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;
        }
    }
}

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

对于。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)); 

假设数组相等意味着两个数组在相等的下标处有相等的元素,则有SequenceEqual答案和IStructuralEquatable答案。

但两者在性能方面都有缺点。

当数组长度不同时,. net Framework中的SequenceEqual实现将不会进行快捷操作,因此它可能会完全枚举其中一个数组,并比较其中的每个元素。 这就是说,取决于。net风格(比如。net 5),它可能会有快捷方式,请看这条评论。因此,对于一个最新的。net项目,SequenceEqual应该是一个不错的选择。

IStructuralEquatable不是通用的,可能会导致每个比较值的装箱。此外,它使用起来不是很简单,并且已经调用了一些helper方法来隐藏它。

从性能角度来看,使用如下代码可能会更好:

bool ArrayEquals<T>(T[] first, T[] second)
{
    if (first == second)
        return true;
    if (first == null || second == null)
        return false;
    if (first.Length != second.Length)
        return false;
    for (var i = 0; i < first.Length; i++)
    {
        if (!first[i].Equals(second[i]))
            return false;
    }
    return true;
}

当然,这也不是检查数组是否相等的“神奇方法”。

所以目前,不,在。net中并没有真正等价于Java Arrays.equals()的东西。