2009-03-16 7 views
35

Ho due array. Ad esempio:Test dell'uguaglianza degli array 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}; 

Qual è il modo migliore per determinare se hanno gli stessi elementi?

+0

sono effettivamente fare con i numeri o è che solo per l'esempio? – mmcdole

+0

Si può usare invece una lista (ha già il metodo Contains)? –

+1

@ed non si trattava di un semplice contiene, ma la determinazione di entrambi gli array ha gli stessi elementi, rileggere la domanda e vedere le risposte :) – eglasius

risposta

20

Utilizzando LINQ è possibile implementare espressamente e 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; 
+0

Grazie per questo snippet di codice. Funziona come un fascino per il mio scenario !! – SudheerKovalam

+5

Trovo che questo sia molto più lento del semplice fare un ciclo e confrontare ogni elemento.Il ciclo potrebbe non essere bello ma molto, molto più veloce. –

+0

Non ne sono sicuro. Per quanto ne so, i LINQ-to-Objects generano tabelle hash intermedie per il loop su join che sono molto più veloci di un ciclo diretto. –

1

Ho trovato la soluzione dettagliata here per essere un modo molto pulito, anche se un po 'prolisso per alcune persone.

La cosa migliore è che funziona anche per altri IEnumerables.

+0

Quel collegamento descrive SequenceEqual (in .NET 3.5) e restituirà false su questi dati poiché sono in un ordine diverso. –

+1

Per riferimento, sarebbe (usando i metodi di estensione) bool areEqual = array1.SequenceEqual (array2); –

10

I valori saranno sempre univoci? Se è così, come circa (dopo aver controllato uguale lunghezza):

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

marc, potrei anche confrontare tramite 'IStructuralEquatable' (tuples and array). Quindi, quando dovrei scegliere 'IStructuralEquatable' vs' SequenceEqual'? –

+1

Non è 'set.SetEquals (array2)' più leggibile? – nawfal

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

Si potrebbe anche usare SequenceEqual, purché gli oggetti IEnumerable sono ordinati per primi

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

sì, ordina/ordina poi SequenceEqual –

6

Adottare estensione (che sono di nuovo in 3.0). Se la lunghezza dell'intersezione dei due array è uguale a quella della loro unione, allora gli array sono uguali.

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

Succinto.

5

Framework 4.0 introdotto interfaccia IStructuralEquatable che aiuta a confrontare tipi come array o tuple:

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

Ciò verifica che ogni array contiene gli stessi valori in ordine.

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