使用 Linq 从列表中删除与属性相交的项目
Posted
技术标签:
【中文标题】使用 Linq 从列表中删除与属性相交的项目【英文标题】:Remove items from list that intersect on property using Linq 【发布时间】:2013-10-04 07:04:50 【问题描述】:我有 2 个共享相同属性的不同对象列表(foo
和 bar
)我们称之为id
。
public List<foo> foo get; set;
public List<bar> bar get; set;
我想从foo
中删除所有具有bar
中不存在的ID 的对象
如何在 linq 中做到这一点?我一直在查看Intersect
、RemoveAll
和Join
,但找不到任何列表类型不同的示例。
【问题讨论】:
【参考方案1】:试试这个:
foo.RemoveAll(x=> !bar.Any(y=>y.Id==x.Id));
!bar.Any(y=>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 一种解决方案是将id
s 的列表从bar
预先收集到一个哈希集中(O(n)),然后将foo
中的每个元素与那个(O (n)) 而不是为foo
中的每个元素遍历bar
列表
是的,我确实在这里看到了 Jon Skeets 示例,但无法将其应用于我的示例 ***.com/questions/853526/…
new HashSet<int>(bar.Select(x => x.id))
应该这样做,假设你没有冲突
使用哈希集来保存您的 id 应该可以工作,请查看 wudziks 示例。以上是关于使用 Linq 从列表中删除与属性相交的项目的主要内容,如果未能解决你的问题,请参考以下文章
使用 LINQ 根据 C# 中的属性值搜索嵌套在另一个列表中的列表中的项目?