Supongo que hay una simple consulta LINQ para hacer esto, simplemente no estoy exactamente seguro de cómo.
Dado este pedazo de código:
class Program
{
static void Main(string[] args)
{
List<Person> peopleList1 = new List<Person>();
peopleList1.Add(new Person() { ID = 1 });
peopleList1.Add(new Person() { ID = 2 });
peopleList1.Add(new Person() { ID = 3 });
List<Person> peopleList2 = new List<Person>();
peopleList2.Add(new Person() { ID = 1 });
peopleList2.Add(new Person() { ID = 2 });
peopleList2.Add(new Person() { ID = 3 });
peopleList2.Add(new Person() { ID = 4 });
peopleList2.Add(new Person() { ID = 5 });
}
}
class Person
{
public int ID { get; set; }
}
Me gustaría realizar una consulta LINQ para darme a todas las personas peopleList2
que no están peopleList1
.
Este ejemplo debería darme dos personas (ID = 4 e ID = 5)
Respuestas:
Esto puede abordarse utilizando la siguiente expresión LINQ:
Una forma alternativa de expresar esto a través de LINQ, que algunos desarrolladores encuentran más legible:
fuente
Si anula la igualdad de las personas, también puede usar:
Except
debería ser significativamente más rápido que laWhere(...Any)
variante ya que puede poner la segunda lista en una tabla hash.Where(...Any)
tiene un tiempo de ejecución deO(peopleList1.Count * peopleList2.Count)
mientras que las variantes basadas enHashSet<T>
(casi) tienen un tiempo de ejecución deO(peopleList1.Count + peopleList2.Count)
.Except
elimina implícitamente los duplicados. Eso no debería afectar su caso, pero podría ser un problema para casos similares.O si desea un código rápido pero no quiere anular la igualdad:
Esta variante no elimina duplicados.
fuente
Equals
hubiera anulado para comparar las identificaciones.O si lo quieres sin negación:
Básicamente dice obtener todo de peopleList2 donde todos los identificadores en peopleList1 son diferentes de id en peopleList2.
Solo un enfoque un poco diferente de la respuesta aceptada :)
fuente
Dado que todas las soluciones hasta la fecha utilizan sintaxis fluida, aquí hay una solución en sintaxis de expresión de consulta, para aquellos interesados:
Creo que es lo suficientemente diferente de las respuestas dadas como para ser de interés para algunos, incluso pensé que probablemente sería subóptimo para las listas. Ahora, para las tablas con ID indexados, este sería definitivamente el camino a seguir.
fuente
Un poco tarde para la fiesta, pero una buena solución que también es compatible con Linq to SQL es:
Felicitaciones a http://www.dotnet-tricks.com/Tutorial/linq/UXPF181012-SQL-Joins-with-C
fuente
La respuesta de Klaus fue excelente, pero ReSharper le pedirá que "Simplifique la expresión LINQ":
var result = peopleList2.Where(p => peopleList1.All(p2 => p2.ID != p.ID));
fuente
Esta extensión enumerable le permite definir una lista de elementos para excluir y una función para encontrar la clave que se usará para realizar la comparación.
Puedes usarlo de esta manera
fuente
Aquí hay un ejemplo de trabajo que obtiene habilidades de TI que un candidato de trabajo no tiene.
fuente
primero, extraiga los identificadores de la colección donde la condición
segundo, use "comparar" para seleccionar los identificadores diferentes a la selección
Obviamente puedes usar x.key! = "TEST", pero es solo un ejemplo
fuente
Una vez que escriba un FuncEqualityComparer genérico, puede usarlo en todas partes.
fuente