web-dev-qa-db-fra.com

Tester l'égalité des tableaux en C #

J'ai deux tableaux. Par exemple:

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

Quel est le meilleur moyen de déterminer s’ils ont les mêmes éléments?

36
SudheerKovalam

En utilisant LINQ vous pouvez l’implémenter de manière expressive et performante:

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;
20
Sedat Kapanoglu

Vous pouvez également utiliser SequenceEqual , à condition que les objets IEnumerable soient triés en premier.

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));
95
Mike Nislick

Les valeurs seront-elles toujours uniques? Si oui, que diriez-vous (après vérification de la longueur égale):

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

Pour une approche plus efficace ( Reflectored à partir du code Microsoft), voir Question sur le dépassement de capacité Comparaison de deux collections pour l’égalité, quel que soit l’ordre de leurs éléments.

6
Ohad Schneider

Utilisez les méthodes d'extension (qui sont nouvelles dans la version 3.0). Si la longueur de l'intersection des deux tableaux est égale à celle de leur union, les tableaux sont égaux.

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

Succinct.

6
Allen
var shared = arr1.Intersect(arr2);
bool equals = arr1.Length == arr2.Length && shared.Count() == arr1.Length;
5
eglasius

Framework 4.0 introduit l'interface IStructuralEquatable qui permet de comparer des types tels que des tableaux ou des tuples:

 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
lukaszk

Cela vérifiera que chaque tableau contient les mêmes valeurs dans l'ordre.

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
daebr

J'ai trouvé la solution détaillée ici être un moyen très propre, bien qu'un peu prolixe pour certaines personnes.

La meilleure chose à faire est que cela fonctionne également pour d'autres IEnumerables.

1
Cerebrus

Bien sûr, il existe de nombreuses façons de comparer des tableaux basés sur la structure. Pour ajouter plus aux réponses ci-dessus, vous pouvez écrire vos propres comparateurs personnalisés. Supposons que vous souhaitiez vérifier si les deux tableaux contiennent des éléments pairs: vous définissez votre comparaison en fonction des règles de gestion de votre application. C'est pourquoi elle est si subjective. 

Voici une façon de le faire, en écrivant votre propre comparateur. Veuillez noter que la méthode GetHashCode () n’a que peu d’importance et que vous devez écrire votre logique d’égalité personnalisée, en vous basant sur le comportement par défaut (comparer les types de référence) .equals () vous donnera des informations différentes. résultats si vous utilisez une autre collection pour contenir les tableaux et que nous disons que ces 2 tableaux contiennent des nombres pairs et sont donc égaux, mais nous enfreignons la règle qui "Si deux valeurs x et y sont égales, elles DOIVENT avoir le même hashcode ". Ne vous inquiétez pas trop ici car nous comparons des nombres entiers. Cela dit, voici l'exemple:

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

        }
    }
}

Après avoir lu les réponses, je me rends compte que personne n’a précisé qu’il fallait inclure le 

   using System.Collections;

ou vous obtiendrez une instruction using manquante ou une erreur de référence Assembly pour l’utilisation de l’interface IStructuralEquatable.

J'espère que ça aidera quelqu'un un jour

0
user7438574
    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;
    }
0
sumit10709893