Удалить элементы из списка, которые пересекаются по свойству, используя 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²), оно не будет работать очень хорошо для больших списков.