2010-11-01 9 views
25

Estoy aprendiendo a escribir lambda expressions, y necesito ayuda para eliminar todos los elementos de una lista que no están en otra lista.Eliminar elementos de la lista 1 no en la lista 2

var list = new List<int> {1, 2, 2, 4, 5}; 
var list2 = new List<int> { 4, 5 }; 

// Remove all list items not in List2 
// new List Should contain {4,5}  
// The lambda expression is the Predicate. 
list.RemoveAll(item => item. /*solution expression here*/); 

// Display results. 
foreach (int i in list) 
{ 
    Console.WriteLine(i); 
} 

Respuesta

49

Puede hacerlo a través de RemoveAll usando Contiene:

list.RemoveAll(item => !list2.Contains(item)); 

otra parte, si lo que desea es la intersección, usando Enumerable.Intersect sería más eficiente:

list = list.Intersect(list2).ToList(); 

La diferencia es, en este último caso, no obtendrá entradas duplicadas. Por ejemplo, si list2 contiene 2, en el primer caso, obtendría {2,2,4,5}, en el segundo, obtendría {2,4,5}.

+0

consulte mi mejora de esta respuesta (a continuación) si compara objetos en lugar de escalares – horace

8

Esta pregunta ha sido marcada como respondida, pero hay una trampa. Si su lista contiene un objeto, en lugar de un escalar, necesita hacer un poco más de trabajo.

Probé esto una y otra vez con Remove() y RemoveAt() y todo tipo de cosas y ninguna de ellas funcionó correctamente. Ni siquiera pude obtener un Contiene() para que funcione correctamente. Nunca coincidió con nada. Me quedé perplejo hasta que tuve la sospecha de que tal vez no podía hacer coincidir el elemento correctamente.

Cuando me di cuenta de esto, reformulé la clase del elemento para implementar IEquatable, y luego comenzó a funcionar.

Aquí está mi solución:

class GenericLookupE : IEquatable<GenericLookupE> 
{ 
    public string ID { get; set; } 

    public bool  Equals(GenericLookupE other) 
    { 
     if (this.ID == other.ID)  return true; 

     return false; 
    } 
} 

Después de hacer esto, el RemoveAll anterior() respuesta por Reed Copsey funcionaba perfectamente para mí.

Ver: http://msdn.microsoft.com/en-us/library/bhkz42b3.aspx

8
list = list.Except(list2).ToList(); 
2

solución más fácil para los objetos que horacio dio:

Si la lista contiene un objeto, en lugar de un escalar, es así de simple, eliminando por una propiedad seleccionada de los objetos:

var a = allActivePatientContracts.RemoveAll(x => !allPatients.Select(y => y.Id).Contains(x.PatientId)); 
Cuestiones relacionadas