2010-11-01 5 views
25

J'apprends à écrire lambda expressions, et j'ai besoin d'aide pour supprimer tous les éléments d'une liste qui ne figurent pas dans une autre liste.Supprimer des éléments de la liste 1 pas dans la liste 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); 
} 

Répondre

49

Vous pouvez le faire via RemoveAll en utilisant Contient:

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

Sinon, si vous voulez juste l'intersection, en utilisant Enumerable.Intersect serait plus efficace:

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

La différence est, dans ce dernier cas, vous n'aurez pas d'entrées en double. Par exemple, si list2 contenait 2, dans le premier cas, vous obtiendriez {2,2,4,5}, dans la seconde, vous obtiendriez {2,4,5}.

+0

Voir mon amélioration de cette réponse (ci-dessous) si vous comparez des objets plutôt que des scalaires – horace

8

Cette question a été marquée comme répondue, mais il y a un problème. Si votre liste contient un objet, plutôt qu'un scalaire, vous devez faire un peu plus de travail.

J'ai essayé cela encore et encore avec Remove() et RemoveAt() et toutes sortes de choses et aucun d'entre eux a fonctionné correctement. Je ne pouvais même pas obtenir un Contient() pour fonctionner correctement. Ne correspond jamais à rien. J'ai été perplexe jusqu'à ce que j'ai le soupçon que peut-être il ne pouvait pas correspondre à l'article correctement.

Lorsque j'ai réalisé cela, j'ai refactorisé la classe élément pour implémenter IEquatable, puis il a commencé à fonctionner.

Voici ma solution:

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

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

     return false; 
    } 
} 

Après avoir fait cela, la réponse RemoveAll() ci-dessus par Reed Copsey a parfaitement fonctionné pour moi.

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

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

solution plus facile pour les objets qu'Horace a donné:

Si votre liste contient un objet, plutôt que d'un scalaire, il est aussi simple que cela, en supprimant par une propriété sélectionnée des objets:

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