2009-03-16 13 views
35

Ich habe zwei Arrays. Zum Beispiel:Testen der Gleichheit von Arrays in 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}; 

Was ist der beste Weg, um zu bestimmen, ob sie die gleichen Elemente haben?

+0

Handeln Sie tatsächlich mit Zahlen oder ist das nur für das Beispiel? – mmcdole

+0

Können Sie stattdessen eine Liste verwenden (enthält bereits die Methode Contains)? –

+1

@ed es ging nicht um eine einfache enthält, aber die Bestimmung beider Array hat die gleichen Elemente, lesen Sie die Frage neu und sehen Sie die Antworten :) – eglasius

Antwort

20

von LINQ verwenden Sie es expressiv und performant implementieren können:

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

Danke für dieses Code-Snippet. Funktioniert wie ein Zauber für mein Szenario !! – SudheerKovalam

+5

Ich finde das viel langsamer als nur eine Schleife zu machen und jeden Gegenstand zu vergleichen.Die Schleife mag nicht so gut aussehen, aber viel, viel schneller. –

+0

Ich bin mir nicht sicher. Soweit ich weiß, generieren LINQ-to-Objects Zwischen-Hash-Tabellen, um Joins zu durchlaufen, die viel schneller sind als eine gerade Schleife. –

1

Ich habe gefunden, die Lösung detailliert here zu sein eine sehr saubere Art, obwohl ein bisschen für einige Leute etwas verblasst.

Das Beste ist, dass es auch für andere IEnumerables funktioniert.

+0

Dieser Link beschreibt SequenceEqual (in .NET 3.5) und gibt für diese Daten false zurück, da sie in einer anderen Reihenfolge sind. –

+1

Als Referenz wäre es (mit Erweiterungsmethoden) bool areEqual = array1.SequenceEqual (array2); –

10

Werden die Werte immer eindeutig sein? Wenn ja, wie etwa (nach gleicher Länge Prüfung):

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

Marc, ich könnte auch über 'IStructuralEquatable' (Tupel und Arrays) vergleichen. Also wann sollte ich 'IStructuralEquatable' gegen' SequenceEqual' wählen? –

+1

Ist 'set.SetEquals (array2)' nicht lesbarer? – nawfal

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

Sie auch SequenceEqual nutzen könnten, sofern die IEnumerable-Objekte sind zuerst sortiert.

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, sortiere/sortiere dann SequenceEqual –

6

Verwenden Sie Erweiterungsmethoden (die in 3.0 neu sind). Wenn die Länge des Schnittpunkts der beiden Arrays der ihrer Union entspricht, sind die Arrays gleich.

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

Prägnant.

5

Framework 4.0 IStructuralEquatable Schnittstelle eingeführt, die Typen wie Arrays oder Tupeln vergleichen hilft:

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

überprüfen Dies wird, dass jedes Array die gleichen Werte in Reihenfolge enthält.

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