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

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


当前回答

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

你会得到不同的结果。

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

其他回答

检查这个线程的答案,它将其中一个数组转换为HashSet,并使用SetEquals与另一个数组进行比较。 但是请注意,这并不检查顺序或副本。

同样对于数组(和元组),你可以使用。net 4.0的新接口:IStructuralComparable和IStructuralEquatable。使用它们不仅可以检查数组是否相等,还可以比较它们。

static class StructuralExtensions
{
    public static bool StructuralEquals<T>(this T a, T b)
        where T : IStructuralEquatable
    {
        return a.Equals(b, StructuralComparisons.StructuralEqualityComparer);
    }

    public static int StructuralCompare<T>(this T a, T b)
        where T : IStructuralComparable
    {
        return a.CompareTo(b, StructuralComparisons.StructuralComparer);
    }
}

{
    var a = new[] { 1, 2, 3 };
    var b = new[] { 1, 2, 3 };
    Console.WriteLine(a.Equals(b)); // False
    Console.WriteLine(a.StructuralEquals(b)); // True
}
{
    var a = new[] { 1, 3, 3 };
    var b = new[] { 1, 2, 3 };
    Console.WriteLine(a.StructuralCompare(b)); // 1
}

你可以使用Enumerable。相交:

int[] array1 = new int[] { 1, 2, 3, 4,5 },
      array2 = new int[] {7,8};

if (array1.Intersect(array2).Any())
    Console.WriteLine("matched");
else
    Console.WriteLine("not matched");

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

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

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

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

可列举的使用。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