2009-03-16 17 views
35

Tengo dos matrices. Por ejemplo:Prueba de igualdad de matrices 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}; 

¿Cuál es la mejor manera de determinar si tienen los mismos elementos?

+0

¿Está realmente tratar con números o es sólo para el ejemplo? – mmcdole

+0

¿Se puede usar una Lista en su lugar (ya tiene el método Contiene)? –

+1

@ed no se trata de un simple contiene, sino que determina que ambas matrices tienen los mismos elementos, vuelve a leer la pregunta y ve las respuestas :) – eglasius

Respuesta

20

Mediante el uso de LINQ se puede implementar expresivamente y 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

Gracias por este fragmento de código. ¡Funciona como un encanto para mi escenario! – SudheerKovalam

+5

Me parece que esto es mucho más lento que simplemente hacer un ciclo y comparar cada elemento.El loop puede no ser tan bonito, pero mucho, mucho más rápido. –

+0

No estoy seguro de eso. Por lo que sé, LINQ-to-Objects genera tablas hash intermedias para iterar sobre uniones que son mucho más rápidas que un bucle directo. –

1

He encontrado la solución detallada here para ser una manera muy limpia, aunque un poco detallada para algunas personas.

Lo mejor es que también funciona para otros IEnumerables.

+0

Ese enlace describe SequenceEqual (en .NET 3.5), y devolverá falso en estos datos ya que están en un orden diferente. –

+1

Como referencia, sería (utilizando métodos de extensión) bool areEqual = array1.SequenceEqual (array2); –

10

¿Los valores siempre serán únicos? Si es así, ¿qué tal (después de revisar la misma longitud):

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

marc, también podría comparar a través de 'IStructuralEquatable' (tuplas y matrices). Entonces, ¿cuándo debería elegir 'IStructuralEquatable' vs' SequenceEqual'? –

+1

¿No es 'set.SetEquals (array2)' más legible? – nawfal

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

También es posible usar SequenceEqual, siempre que los objetos IEnumerable se ordenan primero

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í, ordenar/ordenar luego SequenceEqual –

6

Utilice los métodos de extensión (que son nuevos en 3.0). Si la longitud de la Intersección de las dos matrices es igual a la de su Unión, entonces las matrices son iguales.

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

Succinct.

5

Framework 4.0 interfaz IStructuralEquatable introducido que ayuda a comparar tipos, tales como matrices o tuplas:

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

Esto comprobará que cada matriz contiene los mismos valores en orden.

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