从标准的其他列表中删除列表项

dev*_*per 49 .net c# linq list

我有一份作家名单.

public class Writers{   
    long WriterID { get;set; }
}
Run Code Online (Sandbox Code Playgroud)

我还有两个类型文章列表.

public class Article{
    long ArticleID { get; set; }
    long WriterID { get; set; }
    //and others    
}
Run Code Online (Sandbox Code Playgroud)

所以我的代码是:

List<Article> ArticleList = GetList(1);
List<Article> AnotherArticleList = AnotherList(2);
List<Writers> listWriters = GetAllForbiddenWriters();
Run Code Online (Sandbox Code Playgroud)

我想删除这些记录从ArticleList,AnotherArticleList其中WriterID来自匹配listWriters WriterID.如何在LINQ中执行此操作?

Jon*_*eet 94

如果您确实得到了一个List<T>,我建议您List<T>.RemoveAll在构建一组编写器ID之后使用它:

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));
Run Code Online (Sandbox Code Playgroud)

如果您确实想使用LINQ,可以使用:

articleList = articleList.Where(x => !writerIds.Contains(x.WriterId))
                         .ToList();
anotherArticleList = anotherArticleList
                         .Where(x => !writerIds.Contains(x.WriterId))
                         .ToList();
Run Code Online (Sandbox Code Playgroud)

请注意,这会更改变量但不会修改现有列表 - 因此,如果对同一列表有任何其他引用,则它们将不会看到任何更改.(而RemoveAll修改现有列表.)

  • @bitxwise:不,因为 HashSet 上的“Contains”不会遍历所有内容。它进行哈希查找,时间复杂度为 O(1) 而不是 O(n)。您也不必在每次迭代时获取每个 Writer 的属性。就清晰度而言,我认为最好将“被禁止”的作家视为一个集合,而不是一个列表,因为顺序并不重要,而且我们通过 ID“找到”他们,所以这就是我们所关心的。 (2认同)

bit*_*ise 46

articlesList.RemoveAll(a => listWriters.Exists(w => w.WriterID == a.WriterID));
anotherArticlesList.RemoveAll(a => listWriters.Exists(w => w.WriterID == a.WriterID));
Run Code Online (Sandbox Code Playgroud)

  • 我认为这比接受的答案要好. (5认同)

est*_*mir 7

您可以使用除外

List<car> list1 = GetTheList();
List<car> list2 = GetSomeOtherList();
List<car> result = list2.Except(list1).ToList();
Run Code Online (Sandbox Code Playgroud)