Пересечение запроса LINQ
Если у меня есть IEnumerable, где ClassA предоставляет свойство ID типа long.
Можно ли использовать запрос Linq для получения всех экземпляров ClassA с идентификатором, принадлежащим второму IEnumerable?
Другими словами, можно ли это сделать?
IEnumerable<ClassA> = original.Intersect(idsToFind....)?
где original - это IEnumerable<ClassA>
, а идентификатор idsToFind - IEnumerable<long>
.
Ответы
Ответ 1
Да.
Как ответили другие люди, вы можете использовать Where
, но это будет крайне неэффективно для больших наборов.
Если производительность вызывает беспокойство, вы можете вызвать Join
:
var results = original.Join(idsToFind, o => o.Id, id => id, (o, id) => o);
Если idsToFind
может содержать дубликаты, вам нужно либо вызвать Distinct()
по идентификаторам, либо по результатам, либо заменить Join
на GroupJoin
(Параметры для GroupJoin будут одинаковыми).
Ответ 2
Я отправлю ответ, используя Intersect
.
Это полезно, если вы хотите пересечь 2 IEnumerables
того же типа.
Сначала нам понадобится EqualityComparer
:
public class KeyEqualityComparer<T> : IEqualityComparer<T>
{
private readonly Func<T, object> keyExtractor;
public KeyEqualityComparer(Func<T, object> keyExtractor)
{
this.keyExtractor = keyExtractor;
}
public bool Equals(T x, T y)
{
return this.keyExtractor(x).Equals(this.keyExtractor(y));
}
public int GetHashCode(T obj)
{
return this.keyExtractor(obj).GetHashCode();
}
}
Во-вторых, мы применяем функцию KeyEqualityComparer
к Intersect
:
var list3= list1.Intersect(list2, new KeyEqualityComparer<ClassToCompare>(s => s.Id));
Ответ 3
Вы можете сделать это, но в текущей форме вы хотите использовать метод расширения Where
.
var results = original.Where(x => yourEnumerable.Contains(x.ID));
Intersect
, с другой стороны, найдут элементы, которые находятся в обоих IEnumerable
. Если вы ищете только список идентификаторов, вы можете сделать следующее, которое использует Intersect
var ids = original.Select(x => x.ID).Intersect(yourEnumerable);
Ответ 4
Простым способом было бы:
IEnumerable<ClassA> result = original.Where(a => idsToFind.contains(a.ID));
Ответ 5
Используйте Где метод для фильтрации результатов:
var result = original.Where(o => idsToFind.Contains(o.ID));