2010-05-26 19 views
20

He dos matrices comoLa comparación de matrices usando LINQ en C#

string[] a = { "a", "b", "c" }; 
string[] b = { "a", "b", "c" }; 

que necesitan para comparar las dos matrices usando LINQ.

La comparación debe realizarse solo si ambas matrices tienen el mismo tamaño. Los datos pueden estar en cualquier orden y aún devolver verdadero si todos los valores de a [] y todos los valores de b [] son ​​los mismos.

+0

de x en una de y en b donde x == y seleccione x == y pero no puede corregir ... no almacenar en una variable booleana –

+0

¿Cada matriz tiene valores únicos? ¿Cuándo considera que dos matrices son iguales? si tienen los mismos elementos? los mismos elementos en el mismo orden? –

+0

¿Está buscando una respuesta de bool única si las dos son exactamente iguales o está buscando un cheque para ver si cada elemento es igual que su compañero. –

Respuesta

27
string[] a = { "a", "b" }; 
string[] b = { "a", "b" }; 

return (a.Length == b.Length && a.Intersect(b).Count() == a.Length); 

Después de algunas pruebas de rendimiento:

  • Más de 10.000 pequeñas cadenas - 5ms
  • Más de 100.000 pequeñas cadenas - 99 ms
  • Más de 1.000.000 de pequeñas cadenas - Avg. 601ms
  • Más de 100.000 ~ 500 cadenas de caracteres - 190ms
+1

, pero no creo que el rendimiento sea correcto. la intersección no es operación económica – Andrey

+0

@Andrey - Depende del tamaño de la lista también. –

+4

Sintácticamente, yo diría 'return (a.Length == b.Length && a.Intersect (b) .Count() == a.Length)', pero así soy yo. – ZombieSheep

19

No estoy seguro sobre el rendimiento, pero esto parece funcionar.

string[] a = { "a", "b", "c" }; 
string[] b = { "a", "b", "c" }; 

bool result = a.SequenceEqual(b); 
Assert.AreEqual(true, result); 

Sin embargo, no es independiente de orden por lo que no cumple con los requisitos de OP.

string[] a = { "a", "b", "c" }; 
string[] b = { "a", "c", "b" }; 

bool result = a.SequenceEqual(b); 
Assert.AreEqual(false, result); 
+2

¿Qué quiere decir con "es orden independiente"? SequenceEqual NO es una orden independiente. En su segundo ejemplo de código, devolverá falso –

+0

Tiene razón. Editado –

+0

No downvoting, pero esto no responde la pregunta. Según la operación: 'no en el mismo orden ... pero dos matrices deben tener el mismo tamaño' –

4

si el orden no importa o no puede ser duplicados, entonces tal vez:

public static class IEnumerableExtensions 
{ 
    public static bool HasSameContentsAs<T>(this ICollection<T> source, 
              ICollection<T> other) 
    { 
     if (source.Count != other.Count) 
     { 
      return false; 
     } 
     var s = source 
      .GroupBy(x => x) 
      .ToDictionary(x => x.Key, x => x.Count()); 
     var o = other 
      .GroupBy(x => x) 
      .ToDictionary(x => x.Key, x => x.Count()); 
     int count; 
     return s.Count == o.Count && 
       s.All(x => o.TryGetValue(x.Key, out count) && 
          count == x.Value); 
    } 
} 

de uso:

string[] a = { "a", "b", "c" }; 
string[] b = { "c", "a", "b" }; 

bool containSame = a.HasSameContentsAs(b); 

algunos casos de uso:

  • diferente longitudes (espera falso)

    string[] a = { "a", "b", "c" }; 
    string[] b = { "b", "c" }; 
    
  • orden diferente (esperar cierto)

    string[] a = { "a", "b", "c" }; 
    string[] b = { "b", "c", "a" }; 
    

también funciona si las entradas pueden contener elementos duplicados, aunque no está claro a partir de la cuestión de si se desea o no esa característica , tenga en cuenta:

  • elementos duplicados tienen la misma cuenta (esperar cierto)

    string[] a = { "a", "b", "b", "c" }; 
    string[] b = { "a", "b", "c", "b" }; 
    
  • elementos duplicados con diferentes cantidades de esperar (falsa)

    string[] a = { "a", "b", "b", "b", "c" }; 
    string[] b = { "a", "b", "c", "b", "c" }; 
    
+0

Si compara sus tamaños primero, ¿necesita ambos contener toda la operación? –

+1

@Scott, sí. Considere a = {"a", "b", "c"}; b = {"c", "a". "un" }; misma longitud, pero los elementos únicos en b son un subconjunto de aquellos en una – Handcraftsman

5

Creo que este será siempre un O (n log n) la operación, por lo que acababa de ordenar ambas matrices y compararlos, por ejemplo usando SequenceEqual.

3
IDictionary<int, object> a = new Dictionary<int, object>(); 
IDictionary<int, object> b = new Dictionary<int, object>(); 
a.Add(1, "1"); 
a.Add(2, 2); 
a.Add(3, "3"); 

b.Add(3, "3"); 
b.Add(1, "1"); 
b.Add(2, 2); 

Console.WriteLine(a.All(i => b.Contains(i)) && b.All(i => a.Contains(i))); 
2

Esto funciona correctamente con los duplicados y comprobar cada elemento

a.Length == b.Length && !a.Where((t, i) => t != b[i]).Any() 
Cuestiones relacionadas