web-dev-qa-db-fra.com

Supprimer les éléments de la liste 1 ne figurant pas dans la liste 2

J'apprends à écrire expressions lambda , et j'ai besoin d'aide pour supprimer tous les éléments d'une liste qui ne sont pas dans une autre liste.

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);
}
32
TheMar

Vous pouvez le faire via RemoveAll en utilisant Contient:

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

Alternativement, si vous voulez juste l'intersection, utiliser Enumerable.Intersect serait plus efficace:

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

La différence est que, dans ce dernier cas, vous n'obtiendrez pas de doublons. Par exemple, si list2 en contenait 2, dans le premier cas, vous obtiendrez {2,2,4,5}, dans la seconde, vous obtiendrez {2,4,5}.

62
Reed Copsey

Solution pour les objets (peut-être plus facile que la solution horaces):

Si votre liste contient des objets, plutôt que des scalaires, c'est aussi simple que cela, en supprimant par ne propriété sélectionnée des objets:

    var a = allActivePatientContracts.RemoveAll(x => !allPatients.Select(y => y.Id).Contains(x.PatientId));
11
M.Buschmann

Cette question a été marquée comme ayant reçu une réponse, mais il y a un hic. 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 aucune d'entre elles ne fonctionnait correctement. Je ne pouvais même pas faire fonctionner correctement Contains (). Jamais égalé quoi que ce soit. J'ai été perplexe jusqu'à ce que je soupçonne que cela ne pourrait pas correspondre correctement à l'article.

Quand j'ai réalisé cela, j'ai refactorisé la classe item pour implémenter IEquatable, puis cela 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 de Reed Copsey a parfaitement fonctionné pour moi.

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

9
horace
list = list.Except(list2).ToList();
9
Vuttipong L.