使用 Linq 从列表中删除与属性相交的项目

Posted

技术标签:

【中文标题】使用 Linq 从列表中删除与属性相交的项目【英文标题】:Remove items from list that intersect on property using Linq 【发布时间】:2013-10-04 07:04:50 【问题描述】:

我有 2 个共享相同属性的不同对象列表(foobar)我们称之为id

public List<foo> foo  get; set; 
public List<bar> bar  get; set; 

我想从foo 中删除所有具有bar 中不存在的ID 的对象

如何在 linq 中做到这一点?我一直在查看IntersectRemoveAllJoin,但找不到任何列表类型不同的示例。

【问题讨论】:

【参考方案1】:

试试这个:

foo.RemoveAll(x=> !bar.Any(y=>y.Id==x.Id));

!bar.Any(y=&gt;y.Id==x.Id) 将获取如果项目在 bar 集合中,如果不是,它将从 foo 集合中删除它。

使用哈希集 O(n) 的更好解决方案:

var idsNotToBeRemoved = new HashSet<int>(bar.Select(item => item.Id));                     
foo.RemoveAll(item => !idsNotToBeRemoved.Contains(item.Id));

第二个答案来源:https://***.com/a/4037674/1714342

编辑:

正如@Carra 所说,第一个解决方案适用于小列表,第二个解决方案对于大列表更有效。

【讨论】:

对于小列表,第一个就可以了。如果您使用大列表(> 100 左右),您最好使用第二种解决方案。【参考方案2】:
var foo = foo.Where(f => !bar.Any(b => b.Id == f.Id)).ToList();

请记住,这是一个 O(n²) 解决方案,它不适用于大型列表。

【讨论】:

对此有什么更有效的解决方案? @卡拉 @ojhawkins 一种解决方案是将ids 的列表从bar 预先收集到一个哈希集中(O(n)),然后将foo 中的每个元素与那个(O (n)) 而不是为foo 中的每个元素遍历bar 列表 是的,我确实在这里看到了 Jon Skeets 示例,但无法将其应用于我的示例 ***.com/questions/853526/… new HashSet&lt;int&gt;(bar.Select(x =&gt; x.id)) 应该这样做,假设你没有冲突 使用哈希集来保存您的 id 应该可以工作,请查看 wudziks 示例。

以上是关于使用 Linq 从列表中删除与属性相交的项目的主要内容,如果未能解决你的问题,请参考以下文章

如何根据多个条件并使用 linq 从通用列表中删除项目

使用 LINQ 删除列表中的项目 [重复]

使用 LINQ 根据 C# 中的属性值搜索嵌套在另一个列表中的列表中的项目?

c# 在 LINQ 查询返回的列表中查找项目并将其值与列表中的另一个项目进行比较

LINQ:RemoveAll 并删除元素

将 BootstrapVue 与 Vue.Draggable 一起使用?并将项目从列表中删除到 b 表?