Тестирование равенства массивов в C # - PullRequest
36 голосов
/ 16 марта 2009

У меня есть два массива. Например:

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 ]

96 голосов
/ 01 апреля 2009

Вы также можете использовать SequenceEqual, если объекты IEnumerable отсортированы первыми.

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));
20 голосов
/ 16 марта 2009

Используя 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;
11 голосов
/ 16 марта 2009

Будут ли значения всегда уникальными? Если так, как насчет (после проверки равной длины):

var set = new HashSet<int>(array1);
bool allThere = array2.All(set.Contains);
6 голосов
/ 20 октября 2010

Для наиболее эффективного подхода ( Отражено из кода Microsoft) см. Вопрос переполнения стека Сравнение двух коллекций на равенство независимо от порядка элементов в них .

6 голосов
/ 27 апреля 2009

Используйте методы расширения (которые являются новыми в 3.0). Если длина пересечения двух массивов равна длине их объединения, то массивы равны.

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

Succinct.

5 голосов
/ 30 декабря 2012

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
        }
    } 
5 голосов
/ 16 марта 2009
var shared = arr1.Intersect(arr2);
bool equals = arr1.Length == arr2.Length && shared.Count() == arr1.Length;
1 голос
/ 12 января 2013

Это проверит, что каждый массив содержит одинаковые значения в порядке.

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());
1 голос
/ 16 марта 2009

Я нашел решение, детализированное здесь , очень чистым способом, хотя для некоторых людей оно немного многословно.

Лучше всего то, что он работает и для других IEnumerables.

0 голосов
/ 18 июня 2018

Существует, конечно, много способов сравнения массивов на основе структуры. Чтобы добавить больше к ответам выше, вы можете написать свои собственные пользовательские компараторы. Допустим, вы хотите проверить, содержат ли оба массива четные элементы - вы определяете сравнение на основе бизнес-правил вашего приложения, поэтому оно настолько субъективно.

Вот способ сделать это, написав свой собственный компаратор. Обратите внимание, что метод GetHashCode () не очень заботится, и вы должны в этот момент написать собственную логику равенства, основанную на поведении по умолчанию (сравните ссылочные типы) .equals () даст Вы получите разные результаты, если вы используете другую коллекцию для хранения массивов, и мы говорим, что эти 2 массива содержат четные числа, и поэтому они равны, но мы нарушаем правило, что «Если два значения x и y равны, то они ДОЛЖНЫ иметь тот же хэш-код ". Не беспокойтесь здесь, потому что мы сравниваем целые числа. С этим сказал вот пример:

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.

Надеюсь, это когда-нибудь кому-нибудь поможет

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...