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

ojh*_*ins 19 c# linq

我有两个不同对象列表(foo&bar)共享相同的属性让我们调用它id.

public List<foo> foo { get; set; }
public List<bar> bar { get; set; }
Run Code Online (Sandbox Code Playgroud)

我想删除foo具有不存在的id的所有对象bar

怎么能在linq中完成?我一直在看Intersect,RemoveAll&Join但无法寻找到列表是不同类型的任何实例.

Kam*_*ski 28

试试这个:

foo.RemoveAll(x=> !bar.Any(y=>y.Id==x.Id));
Run Code Online (Sandbox Code Playgroud)

!bar.Any(y=>y.Id==x.Id)如果项目在bar收集中将获得,如果不是它将从foo集合中删除它.

使用hashset O(n)的更好解决方案:

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

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

编辑:

正如@Carra所说,第一种解决方案适用于小型列表,其次对大型列表更有效.

  • 对于小型列表,第一个会做.如果你使用大列表(> 100左右),你最好使用第二个解决方案. (2认同)

Car*_*rra 8

var foo = foo.Where(f => !bar.Any(b => b.Id == f.Id)).ToList();
Run Code Online (Sandbox Code Playgroud)

请记住,这是一个O(n²)解决方案,它对大型列表不会很好.