una son listas lista iguales elementos comparar c# linq list

son - comparar elementos de una lista c#



La forma más rápida de comparar dos List<> (7)

¿Cuál es el método más rápido (y menos intensivo en recursos) para comparar dos elementos masivos (> 50,000) y, como resultado, tiene dos listas como las siguientes:

  1. ítems que aparecen en la primera lista, pero no en la segunda
  2. ítems que aparecen en la segunda lista pero no en la primera

Actualmente estoy trabajando con List o IReadOnlyCollection y resuelvo este problema en una consulta de linq:

var list1 = list.Where(i => !list2.Contains(i)).ToList(); var list2 = list2.Where(i => !list.Contains(i)).ToList();

Pero esto no funciona tan bien como me gustaría. ¿Alguna idea de hacer esto más rápido y menos intensivo de recursos ya que necesito procesar muchas listas?


He usado este código para comparar dos listas que tienen un millón de registros.

Este método no tomará mucho tiempo

//Method to compare two list of string private List<string> Contains(List<string> list1, List<string> list2) { List<string> result = new List<string>(); result.AddRange(list1.Except(list2, StringComparer.OrdinalIgnoreCase)); result.AddRange(list2.Except(list1, StringComparer.OrdinalIgnoreCase)); return result; }


Más eficiente sería usar Except . Except :

var inListButNotInList2 = list.Except(list2); var inList2ButNotInList = list2.Except(list);

Este método se implementa mediante el uso de la ejecución diferida. Eso significa que podrías escribir, por ejemplo:

var first10 = inListButNotInList2.Take(10);

También es eficiente ya que internamente usa un Set<T> para comparar los objetos. Funciona al recoger primero todos los valores distintos de la segunda secuencia, y luego transmitir los resultados de la primera, comprobando que no se hayan visto antes.


No es para este problema, pero aquí hay un código para comparar listas para iguales y no! objetos idénticos:

public class EquatableList<T> : List<T>, IEquatable<EquatableList<T>> where T : IEquatable<T> /// <summary> /// True, if this contains element with equal property-values /// </summary> /// <param name="element">element of Type T</param> /// <returns>True, if this contains element</returns> public new Boolean Contains(T element) { return this.Any(t => t.Equals(element)); } /// <summary> /// True, if list is equal to this /// </summary> /// <param name="list">list</param> /// <returns>True, if instance equals list</returns> public Boolean Equals(EquatableList<T> list) { if (list == null) return false; return this.All(list.Contains) && list.All(this.Contains); }


Puede ser divertido, pero funciona para mí

string.Join ("", List1)! = string.Join ("", List2)


Si desea que los resultados sean insensibles a las mayúsculas y minúsculas , lo siguiente funcionará:

List<string> list1 = new List<string> { "a.dll", "b1.dll" }; List<string> list2 = new List<string> { "A.dll", "b2.dll" }; var firstNotSecond = list1.Except(list2, StringComparer.OrdinalIgnoreCase).ToList(); var secondNotFirst = list2.Except(list1, StringComparer.OrdinalIgnoreCase).ToList();

firstNotSecond contendría b1.dll

secondNotFirst contendría b2.dll


Use Except :

var firstNotSecond = list1.Except(list2).ToList(); var secondNotFirst = list2.Except(list1).ToList();

Sospecho que hay enfoques que en realidad serían marginalmente más rápidos que esto, pero incluso esto será mucho más rápido que tu enfoque O (N * M).

Si desea combinar estos, puede crear un método con la anterior y luego una declaración de devolución:

return !firstNotSecond.Any() && !secondNotFirst.Any();


intente de esta manera:

var difList = list1.Where(a => !list2.Any(a1 => a1.id == a.id)) .Union(list2.Where(a => !list1.Any(a1 => a1.id == a.id)));