Удалить элементы из списка, которые пересекаются по свойству, используя Linq

У меня есть 2 списка разных объектов (foo и bar), которые имеют одно и то же свойство, и назовите его id.

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

Я хочу удалить все объекты из foo, у которых есть id, который не существует в bar

Как это можно сделать в linq? Я смотрел Intersect, RemoveAll и Join, но не могу найти ни одного примера, когда списки имеют другой тип.

Ответы

Ответ 1

Попробуйте следующее:

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

!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));

источник второго ответа: fooobar.com/questions/329803/...

EDIT:

как сказал @Carra, первое решение подходит для небольших списков, а второе - для больших списков.

Ответ 2

var foo = foo.Where(f => !bar.Any(b => b.Id == f.Id)).ToList();

Просто имейте в виду, что это решение O (n²), оно не будет работать очень хорошо для больших списков.