web-dev-qa-db-fra.com

Supprimer des éléments de liste d'une autre liste avec des critères

j'ai une liste d'écrivains.

public class Writers{   
    long WriterID { get;set; }
}

J'ai aussi deux listes de type Article.

public class Article{
    long ArticleID { get; set; }
    long WriterID { get; set; }
    //and others    
}

donc le code que j'ai est:

List<Article> ArticleList = GetList(1);
List<Article> AnotherArticleList = AnotherList(2);
List<Writers> listWriters = GetAllForbiddenWriters();

Je souhaite supprimer ces enregistrements de ArticleList, AnotherArticleListWriterID correspond à listWritersWriterID. Comment faire cela dans LINQ?

48
developer

Si vous avez réellement un List<T>, Je vous suggère d'utiliser List<T>.RemoveAll , après avoir construit un ensemble d'ID d'écrivain:

HashSet<long> writerIds = new HashSet<long>(listWriters.Select(x => x.WriterID));

articleList.RemoveAll(x => writerIds.Contains(x.WriterId));
anotherArticleList.RemoveAll(x => writerIds.Contains(x.WriterId));

Si vous voulez utiliser LINQ, vous pouvez utiliser:

articleList = articleList.Where(x => !writerIds.Contains(x.WriterId))
                         .ToList();
anotherArticleList = anotherArticleList
                         .Where(x => !writerIds.Contains(x.WriterId))
                         .ToList();

Notez que cela modifie la variable mais ne modifie pas la liste existante - donc s'il y a d'autres références à la même liste, ils ne verront pas tout changement. (Alors que RemoveAll modifie la liste existante.)

94
Jon Skeet
articlesList.RemoveAll(a => listWriters.Exists(w => w.WriterID == a.WriterID));
anotherArticlesList.RemoveAll(a => listWriters.Exists(w => w.WriterID == a.WriterID));
44
bitxwise

Juste une astuce de conception, votre classe devrait s'appeler Writer (forme singulière), pas Writers (pluriel). Chaque élément de votre liste représente un seul auteur, n'est-ce pas?

1
danijels

Je ne vois pas vraiment quelle est la difficulté que vous rencontrez ...

Pourquoi ne filtrez-vous pas/supprimez-vous simplement les données de vos listes en utilisant une simple boucle for? (Notez qu'une boucle foreach ne fonctionnera certainement pas si vous itérez pendant la modification/modification de l'objet itéré)

for (int i = ArticleList.Count -1; i >= 0; i--)
{
    for (int j = 0; j < listWriters.Count; j++)
    {
        if (ArticleList[i].WriterId == listWriters[j].WriterID )
            ArticleList.RemoveAt(i);
    }            
}

L'astuce d'itération vers l'arrière résout le paradigme "supprimer les éléments lors de l'itération".

1
Mehdi LAMRANI

Vous pouvez utiliser Sauf :

List<car> list1 = GetTheList();
List<car> list2 = GetSomeOtherList();
List<car> result = list2.Except(list1).ToList();
0
bestinamir