Verifique si dos listas son iguales

Tengo una clase de la siguiente manera:

public class Tag { public Int32 Id { get; set; } public String Name { get; set; } } 

Y tengo dos listas de tags:

 List tags1; List tags2; 

Usé la selección de LINQ para obtener los id de cada lista de tags. Y entonces:

 List ids1 = new List { 1, 2, 3, 4 }; List ids2 = new List { 1, 2, 3, 4 }; List ids3 = new List { 2, 1, 3, 4 }; List ids4 = new List { 1, 2, 3, 5 }; List ids5 = new List { 1, 1, 3, 4 }; 

ids1 debe ser igual a ids2 e ids3 … Ambos tienen los mismos números.

ids1 no debe ser igual a ids4 y a ids5 …

Intenté lo siguiente:

 var a = ints1.Equals(ints2); var b = ints1.Equals(ints3); 

Pero ambos me dan falso.

¿Cuál es la forma más rápida de verificar si las listas de tags son iguales?

ACTUALIZAR

Estoy buscando POSTS que TAGS son exactamente los mismos que los TAGS en un BOOK.

 IRepository repository = new Repository(new Context()); IList tags = new List { new Tag { Id = 1 }, new Tag { Id = 2 } }; Book book = new Book { Tags = new List { new Tag { Id = 1 }, new Tag { Id = 2 } } }; var posts = repository .Include(x => x.Tags) .Where(x => new HashSet(tags.Select(y => y.Id)).SetEquals(book.Tags.Select(y => y.Id))) .ToList(); 

Estoy usando Entity Framework y me sale el error:

Se produjo una excepción del tipo ‘System.NotSupportedException’ en mscorlib.dll pero no se manejó en el código de usuario

Información adicional: LINQ to Entities no reconoce el método ‘Boolean SetEquals (System.Collections.Generic.IEnumerable`1 [System.Int32])’ y este método no se puede traducir a una expresión de tienda.

¿Cómo puedo solucionar esto?

Use SequenceEqual para verificar la igualdad de secuencia porque el método Equals comprueba la igualdad de referencia .

 var a = ints1.SequenceEqual(ints2); 

O si no te importan los elementos, utiliza Enumerable.All métodos:

 var a = ints1.All(ints2.Contains); 

La segunda versión también requiere otra verificación para Count porque devolvería true incluso si ints2 contiene más elementos que ints1 . Entonces, la versión más correcta sería algo como esto:

 var a = ints1.All(ints2.Contains) && ints1.Count == ints2.Count; 

Para verificar la desigualdad, simplemente revertir el resultado del método All :

 var a = !ints1.All(ints5.Contains) 

List equality no los verifica elemento por elemento. Puede usar el método SequenceEqual de LINQ para eso:

 var a = ints1.SequenceEqual(ints2); 

Para ignorar el orden, use SetEquals :

 var a = new HashSet(ints1).SetEquals(ints2); 

Esto debería funcionar, porque está comparando secuencias de ID, que no contienen duplicados. Si lo hace, y necesita tener en cuenta los duplicados, la forma de hacerlo en tiempo lineal es componer un diccionario de recuentos basado en hash, agregar uno para cada elemento de la primera secuencia, restar uno para cada elemento del segundo secuencia, y verificar si los recuentos resultantes son todos ceros:

 var counts = ints1 .GroupBy(v => v) .ToDictionary(g => g.Key, g => g.Count()); var ok = true; foreach (var n in ints2) { int c; if (counts.TryGetValue(n, out c)) { counts[n] = c-1; } else { ok = false; break; } } var res = ok && counts.Values.All(c => c == 0); 

Finalmente, si está bien con una solución O(N*LogN) , puede ordenar las dos secuencias y compararlas para igualdad usando SequenceEqual .

 Enumerable.SequenceEqual(FirstList.OrderBy(fElement => fElement), SecondList.OrderBy(sElement => sElement))