繁体   English   中英

C#LINQ集合的“内部联接”

[英]C# LINQ “inner join” of collections

基本上,我有一个IEnumerable<IEnumerable<T>>对象,并且我想从中获取所有集合中存在的对象的IEnumerable<T>

我正在尝试编写尽可能优雅的代码,并且想知道这样做是否有一些LINQ技巧,最好是单行代码。 如果有帮助,则两个IEnumerable都为ISet

目前,我正在使用类似于以下代码:

// Some starting data - collection of collections
HashSet<HashSet<ulong>> data = new HashSet<HashSet<ulong>> { new HashSet<ulong> { 1, 2, 3 }, new HashSet<ulong> { 2, 3, 4 }, new HashSet<ulong> { 3, 4, 5 } };

// Flatten collection of collections into a single collection with unique elements
HashSet<ulong> result = new HashSet<ulong>(data.SelectMany(set => set));

// Remove from it all elements that are missing from 1 or more initial collections
result.RemoveWhere(number => data.Any(set => !set.Contains(number)));

// The result is: HashSet<ulong> { 3 }

它可以工作,但是我在这里做了几件事情,例如两次枚举初始集合,创建半就绪结果以及迭代+从中删除元素。

我很确定应该有一个选项可以通过LINQ一次完成,我基本上是在寻找类似的东西:

HashSet<HashSet<ulong>> data = new HashSet<HashSet<ulong>> { new HashSet<ulong> { 1, 2, 3 }, new HashSet<ulong> { 2, 3, 4 }, new HashSet<ulong> { 3, 4, 5 } };elements
HashSet<ulong> result = data.LinqInnerJoinMagic(set => set);

C#中是否存在类似的东西? 也许作为扩展方法? 我尽力使用LINQ Join()但是我找不到如何使它适应我的示例的方法,我会很乐于助人,很可能答案很简单,以至于我找不到真正的答案。它。

先感谢您!

您可以使用HashSet<T>.IntersectWith

HashSet<ulong> result = data.First();
foreach (HashSet<ulong> set in data.Skip(1))
    result.IntersectWith(set);

修改当前HashSet<T>对象,使其仅包含该对象和指定集合中存在的元素。

集合与相交相结合将为您提供所有集合中存在的公共元素。

var orderedData = data.ToList();
var commonSet = orderedData.Skip(1).Aggregate((IEnumerable<ulong>)(orderedData.First()), (c, n) => c.Intersect(n));

尝试这个:

var result = new HashSet<ulong>(
      data.SelectMany(x => x).Where(x => data.All(z => z.Contains(x)))
);

参见MSDN

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM