在C#中测试数组的相等性

时间:2009-03-16 06:32:35

标签: c# arrays

我有两个数组。例如:

int[] Array1 = new[] {1, 2, 3, 4, 5, 6, 7, 8, 9};
int[] Array2 = new[] {9, 1, 4, 5, 2, 3, 6, 7, 8};

确定它们是否具有相同元素的最佳方法是什么?

11 个答案:

答案 0 :(得分:96)

如果首先对IEnumerable对象进行排序,您也可以使用SequenceEqual

int[] a1 = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };    
int[] a2 = new[] { 9, 1, 4, 5, 2, 3, 6, 7, 8 };    

bool equals = a1.OrderBy(a => a).SequenceEqual(a2.OrderBy(a => a));

答案 1 :(得分:20)

通过使用LINQ,您可以明确而高效地实现它:

var q = from a in ar1
        join b in ar2 on a equals b
        select a;

bool equals = ar1.Length == ar2.Length && q.Count() == ar1.Length;

答案 2 :(得分:11)

值是否始终是唯一的?如果是这样,那么(检查相等的长度后):

var set = new HashSet<int>(array1);
bool allThere = array2.All(set.Contains);

答案 3 :(得分:6)

使用扩展方法(3.0中的新增功能)。如果两个数组的交集长度等于它们的Union的长度,那么数组是相等的。

bool equals = arrayA.Intersect(arrayB).Count() == arrayA.Union(arrayB).Count()

简洁。

答案 4 :(得分:6)

要获得最有效的方法(Microsoft代码Reflectored),请参阅Stack Overflow问题 Comparing two collections for equality irrespective of the order of items in them

答案 5 :(得分:5)

var shared = arr1.Intersect(arr2);
bool equals = arr1.Length == arr2.Length && shared.Count() == arr1.Length;

答案 6 :(得分:5)

Framework 4.0引入了IStructuralEquatable接口,有助于比较数组或元组等类型:

 class Program
    {
        static void Main()
        {
            int[] array1 = { 1, 2, 3 };
            int[] array2 = { 1, 2, 3 };
            IStructuralEquatable structuralEquator = array1;
            Console.WriteLine(array1.Equals(array2));                                  // False
            Console.WriteLine(structuralEquator.Equals(array2, EqualityComparer<int>.Default));  // True

            // string arrays
            string[] a1 = "a b c d e f g".Split();
            string[] a2 = "A B C D E F G".Split();
            IStructuralEquatable structuralEquator1 = a1;
            bool areEqual = structuralEquator1.Equals(a2, StringComparer.InvariantCultureIgnoreCase);

            Console.WriteLine("Arrays of strings are equal:"+  areEqual);

            //tuples
            var firstTuple = Tuple.Create(1, "aaaaa");
            var secondTuple = Tuple.Create(1, "AAAAA");
            IStructuralEquatable structuralEquator2 = firstTuple;
            bool areTuplesEqual = structuralEquator2.Equals(secondTuple, StringComparer.InvariantCultureIgnoreCase);

            Console.WriteLine("Are tuples equal:" + areTuplesEqual);
            IStructuralComparable sc1 = firstTuple;
            int comparisonResult = sc1.CompareTo(secondTuple, StringComparer.InvariantCultureIgnoreCase);
            Console.WriteLine("Tuples comarison result:" + comparisonResult);//0
        }
    } 

答案 7 :(得分:1)

我发现解决方案详细here是一种非常干净的方式,虽然对某些人来说有点冗长。

最好的是它也适用于其他IEnumerables。

答案 8 :(得分:1)

这将检查每个数组是否按顺序包含相同的值。

int[] ar1 = { 1, 1, 5, 2, 4, 6, 4 };
int[] ar2 = { 1, 1, 5, 2, 4, 6, 4 };

var query = ar1.Where((b, i) => b == ar2[i]);

Assert.AreEqual(ar1.Length, query.Count());

答案 9 :(得分:0)

    public static bool ValueEquals(Array array1, Array array2)
    {
        if( array1 == null && array2 == null )
        {
            return true;
        }

        if( (array1 == null) || (array2 == null) )
        {
            return false;
        }

        if( array1.Length != array2.Length )
        {
            return false;
        }
        if( array1.Equals(array2))
        {
           return true;
        }
        else
        {
            for (int Index = 0; Index < array1.Length; Index++)
            {
                if( !Equals(array1.GetValue(Index), array2.GetValue(Index)) )
                {
                    return false;
                }
            }
        }
        return true;
    }

答案 10 :(得分:0)

当然,有很多方法可以根据结构比较数组。要在上面的答案中添加更多内容,您可以编写自己的自定义比较器。我们假设您要检查两个数组是否包含偶数元素 - 您可以根据应用程序的业务规则定义比较,这就是为什么它如此主观。

这是一种方法,编写自己的比较器。请注意,没有太多关心 GetHashCode()方法,此时您必须根据默认行为(比较引用类型)编写自定义相等逻辑.equals()将如果你使用另一个集合来保存数组,你会得到不同的结果,我们说这两个数组包含偶数,因此它们是相等的,但是我们打破了规则#34;如果两个值x和y的计算结果相等那么它们必须具有相同的哈希码&#34;。不要在这里过分担心,因为我们正在比较整数。这就是说这里的例子:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp5
{
    class EvenComparer : EqualityComparer<int>
    {


        public override bool Equals(int x, int y)
        {
            if((x % 2 == 0 && y % 2 == 0))
            {
                return true;
            }

            return false;

        }

        public override int GetHashCode(int obj)
        {
            return obj.GetHashCode();
        }
    }


    class Program
    {
        static void Main(string[] args)
        {

            //If you want to check whether the arrays are equal in the sense of containing the same elements in the same order

            int[] Array1 =  { 2, 4, 6};
            int[] Array2 =  {8, 10, 12 };



            string[] arr1 = { "Jar Jar Binks", "Kill! Kill!", "Aaaaargh!" };
            string[] arr2 = { "Jar Jar Binks", "Kill! Kill!", "Aaaaargh!" };

            bool areEqual = (arr1 as IStructuralEquatable).Equals(arr2, StringComparer.Ordinal);
            bool areEqual2 = (Array1 as IStructuralEquatable).Equals(Array2, new EvenComparer());

            Console.WriteLine(areEqual);
            Console.WriteLine(areEqual2);


            Console.WriteLine(Array1.GetHashCode());
            Console.WriteLine(Array2.GetHashCode());

        }
    }
}

阅读完答案后,我意识到没有人指定你必须包括

   using System.Collections;

命名空间或使用IStructuralEquatable接口时将丢失using指令或程序集引用错误。

希望有一天能帮到某人