C# 使用Linq从与属性相交的列表中删除项
我有两个不同对象的列表(C# 使用Linq从与属性相交的列表中删除项,c#,linq,C#,Linq,我有两个不同对象的列表(foo&bar),它们共享相同的属性,我们可以称之为id public List<foo> foo { get; set; } public List<bar> bar { get; set; } 公共列表foo{get;set;} 公共列表栏{get;set;} 我想从foo中删除id在bar中不存在的所有对象 如何在linq中实现这一点?我一直在查看Intersect,RemoveAll和Join,但找不到任何列表类型不同的示例。尝试以下方
foo
&bar
),它们共享相同的属性,我们可以称之为id
public List<foo> foo { get; set; }
public List<bar> bar { get; set; }
公共列表foo{get;set;}
公共列表栏{get;set;}
我想从foo
中删除id在bar
中不存在的所有对象
如何在linq中实现这一点?我一直在查看Intersect
,RemoveAll
和Join
,但找不到任何列表类型不同的示例。尝试以下方法:
foo.RemoveAll(x=> !bar.Any(y=>y.Id==x.Id));
!任何(y=>y.Id==x.Id)
都将在项目位于bar
集合中时获得,如果项目不在foo
集合中,则将其从foo
集合中删除
使用hashset O(n)的更好解决方案:
var idsNotToBeRemoved=newhashset(bar.Select(item=>item.Id));
foo.RemoveAll(item=>!idsNotToBeRemoved.Contains(item.Id));
第二个答案的来源:
编辑:
正如@Carra所说,第一种解决方案适用于小列表,第二种解决方案适用于大列表
var foo = foo.Where(f => !bar.Any(b => b.Id == f.Id)).ToList();
请记住,这是一个O(n²)解决方案,对于大列表来说效果不太好。什么是更有效的解决方案@Carra@ojhawkins一种解决方案是将
bar
中的id
s列表预先收集到一个hashset(O(n))中,然后将foo
中的每个元素与该(O(n))进行比较我没有在foo
中为每个元素遍历bar
列表,而是在这里看到了Jon Skeets示例,但无法将其应用于我的示例新哈希集(bar.Select(x=>x.id))
应该做的,假设没有冲突使用哈希集保存id应该可行,请检查wudziks示例。对于小列表,第一个就行了。如果您使用的是大列表(>100左右),则最好使用第二种解决方案。
var foo = foo.Where(f => !bar.Any(b => b.Id == f.Id)).ToList();