2009-03-16 8 views
35

J'ai deux tableaux. Par exemple:Test de l'égalité des tableaux en C#

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

Quelle est la meilleure façon de déterminer s'ils ont les mêmes éléments?

+0

Êtes-vous réellement chiffrées ou est-ce juste pour l'exemple? – mmcdole

+0

Pouvez-vous utiliser une liste à la place (a déjà la méthode Contains)? –

+1

@ed il ne s'agissait pas d'un simple contenant, mais déterminer les deux tableaux a les mêmes éléments, relire la question et voir les réponses :) – eglasius

Répondre

20

En utilisant LINQ vous pouvez le mettre en œuvre expressivement et performant:

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; 
+0

Merci pour ce petit bout de code. Fonctionne comme un charme pour mon scénario !! – SudheerKovalam

+5

Je trouve que c'est beaucoup plus lent que de faire une boucle et de comparer chaque élément.La boucle n'est peut-être pas aussi belle, mais beaucoup plus rapide. –

+0

Je ne suis pas sûr de ça. Pour autant que je sache, LINQ-to-Objects génère des tables de hachage intermédiaires pour boucler des jointures qui sont beaucoup plus rapides qu'une boucle droite. –

1

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

La meilleure chose est que cela fonctionne aussi pour d'autres IEnumerables.

+0

Ce lien décrit SequenceEqual (dans .NET 3.5), et retournera false sur ces données car elles sont dans un ordre différent. –

+1

Pour référence, ce serait (en utilisant des méthodes d'extension) bool areEqual = array1.SequenceEqual (array2); –

10

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

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

marc, je pourrais également comparer via 'IStructuralEquatable' (tuples et tableaux). Alors, quand devrais-je choisir 'IStructuralEquatable' vs' SequenceEqual'? –

+1

Est-ce que 'set.SetEquals (array2)' n'est pas plus lisible? – nawfal

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

Vous pouvez également utiliser SequenceEqual, à condition que les objets IEnumerable sont 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)); 
+2

yep, trier/commander puis SequenceEqual –

6

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

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

Succinct.

5

Framework 4.0 introduit une interface IStructuralEquatable qui permet de comparer les 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 
     } 
    } 
1

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