相交LINQ查询
如果我有一个IEAumerable,其中ClassA公开一个types为long的ID属性。 是否有可能使用Linq查询来获取属于第二个IEnumerable的ID的所有ClassA实例?
换句话说,这可以做到吗?
IEnumerable<ClassA> = original.Intersect(idsToFind....)?
其中original是一个IEnumerable<ClassA>
,idsToFind是IEnumerable<long>
。
是。
正如其他人所回答的那样,你可以使用Where
,但是对于大集合来说效率会非常低。
如果性能是一个问题,你可以打电话Join
:
var results = original.Join(idsToFind, o => o.Id, id => id, (o, id) => o);
如果idsToFind
可以包含重复项,则需要在ID或结果上调用Distinct()
,或者用idsToFind
replaceJoin
与GroupJoin
的参数相同)。
我将使用Intersect
发布答案。
如果要交叉2个相同types的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));
你可以做到这一点,但在目前的forms,你要使用Where
扩展方法。
var results = original.Where(x => yourEnumerable.Contains(x.ID));
另一方面Intersect
会发现在两个IEnumerable
的元素。 如果你正在寻找一个ID列表,你可以做以下利用Intersect
var ids = original.Select(x => x.ID).Intersect(yourEnumerable);
一个简单的方法是:
IEnumerable<ClassA> result = original.Where(a => idsToFind.contains(a.ID));
使用Where方法来筛选结果:
var result = original.Where(o => idsToFind.Contains(o.ID));