我有两个不同类型的对象集合。让我们称它们为类型 ALPHA 和类型 BRAVO。这些类型中的每一种都有一个属性,即对象的“ID”。类中没有重复的 ID,因此对于任何给定的 ID,最多有一个 ALPHA 和一个 BRAVO 实例。我需要做的是将它们分为 3 类:
- ALPHA 中未出现在 BRAVO 集合中的 ID 实例;
- BRAVO 中未出现在 ALPHA 集合中的 ID 实例;
- 出现在两个集合中的 ID 实例。
在所有 3 种情况下,我都需要手头有集合中的实际对象,以便进行后续操作。
我知道对于第 3 种情况,我可以这样做:
var myCorrelatedItems = myAlphaItems.Join(myBravoItems, alpha => alpha.Id, beta => beta.Id, (inner, outer) => new
{
alpha = inner,
beta = outer
});
我还可以为#1 和#2 情况编写代码,看起来像
var myUnmatchedAlphas = myAlphaItems.Where(alpha=>!myBravoItems.Any(bravo=>alpha.Id==bravo.Id));
对于 unMatchedBravos 也是如此。不幸的是,这会导致多次迭代 alpha 集合(可能非常大!),以及多次迭代 bravos 集合(也可能非常大!)。
有什么方法可以统一这些查询概念,从而最大限度地减少对列表的迭代?这些集合可以包含数千个项目。
最佳答案
如果您只对 ID 感兴趣,
var alphaIds = myAlphaItems.Select(alpha => alpha.ID);
var bravoIds = myBravoItems.Select(bravo => bravo.ID);
var alphaIdsNotInBravo = alphaIds.Except(bravoIds);
var bravoIdsNotInAlpha = bravoIds.Except(alphaIds);
如果你想要 alpha 和 bravos 本身,
var alphaIdsSet = new HashSet<int>(alphaIds);
var bravoIdsSet = new HashSet<int>(bravoIds);
var alphasNotInBravo = myAlphaItems
.Where(alpha => !bravoIdsSet.Contains(alpha.ID));
var bravosNotInAlpha = myBravoItems
.Where(bravo => !alphaIdsSet.Contains(bravo.ID));
编辑: 其他一些选项:
-
ExceptBy
method来自 MoreLinq . Enumerable.ToDictionary
方法。- 如果两种类型都继承自一个通用类型(例如
IHasId
接口(interface)),您可以编写自己的IEqualityComparer<T>
执行;Enumerable.Except
has an overload接受相等比较器作为参数。
关于c# - LINQ 组合查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4098176/