提取IEnumerable <t>的项目,其Key-Value等于IEnumerable <u> </u> </t>中的一个KeyValues

时间:2011-05-29 13:34:58

标签: c# .net linq collections ienumerable

我想提取IEnumerable序列的所有项,其Key-Value等于另一个IEnumerable序列中的一个Key-Values。 请考虑第一个序列是'T'类型,其中T是:

class T
{
    int SpecificValue;
    // other payload
}

,第二个序列是'U'类型,其中U是:

class U
{
    int SpecificValueOfSameType;
    // other payload (different from class T)
}

有可能吗?

作为一个副节点:我使用术语“Key”-Value,但不能保证这个值在两个序列中都是唯一的。它应该有助于更详细地解释我的要求。在实际代码中,我可以想象有一种Compare-Func参数。)

4 个答案:

答案 0 :(得分:3)

听起来你正在寻找Join

ts.Join(us, t => t.SpecificValue, u => u.SpecificValueOfSameType, (t, u) => new Something)

答案 1 :(得分:1)

试试这个:

Ts.Where(t => Us.Select(u => u.SpecificValueOfSameType).Contains(t.SpecificValue))

答案 2 :(得分:1)

正如K Ivanov所示,您可以使用Contains - 但如果您的收藏相当大,那么您最好先将它们放入HashSet中:

var keys = new HashSet<T>(us.Select(u => u.SpecificValueOfSameType));
var query = ts.Where(t => keys.Contains(t.SpecificValue));
编辑:我错过了任何一个集合中都可能存在重复键的事实。使用上面的代码就可以了,但是对于连接不起作用(至少,不是没有不同的调用)。

“Compare-Func”参数的含义并不完全清楚。如果这只是一种从序列中提取密钥的方法,那很好。如果它是比较两个键相等的函数,那就是另一个问题。这意味着你不能指散列。

答案 3 :(得分:0)

  

无法保证此值在两个序列中都是唯一的。

嗯,这清楚地表明你想远离大多数联盟。

GroupJoin怎么样?当有多个匹配时,这种类型的连接不会引入重复。

from t in tSource
join u in uSource
  on t.SpecificValue
  equals u.SpecificValueOfSameType
  into g
where g.Any()
select t;

也写成:

tSource.GroupJoin(uSource,
  t => t.SpecificValue,
  u => u.SpecificValueOfSameType,
  (t, g) => new {t, g})
.Where(x => x.g.Any())
.Select(x => x.t)