[英]C# LINQ “inner join” of collections
Basically I have a IEnumerable<IEnumerable<T>>
object and I want to get from it IEnumerable<T>
of objects that exist in all of the collections. 基本上,我有一个IEnumerable<IEnumerable<T>>
对象,并且我想从中获取所有集合中存在的对象的IEnumerable<T>
。
I'm trying to code that as elegant as possible, and I'm wondering if there is some LINQ trick of doing that, preferably one-liner. 我正在尝试编写尽可能优雅的代码,并且想知道这样做是否有一些LINQ技巧,最好是单行代码。 If it can help, both IEnumerable
s are ISet
. 如果有帮助,则两个IEnumerable
都为ISet
。
Currently I'm using a code similar to below: 目前,我正在使用类似于以下代码:
// 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 }
It works, but I'm doing several things here such as enumerating initial collection twice, creating a half-ready result and iterating + removing elements from it. 它可以工作,但是我在这里做了几件事情,例如两次枚举初始集合,创建半就绪结果以及迭代+从中删除元素。
I'm pretty sure there should be an option to do that in one-go with LINQ, I'm basically looking for something like: 我很确定应该有一个选项可以通过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);
Does something like this exist in C#? C#中是否存在类似的东西? Maybe as an extension method? 也许作为扩展方法? I tried hard to make use of LINQ Join()
but I couldn't find out how to adapt it to my example, I'd appreciate a helpful hand, it's very likely that the answer is so simple that I can't really find it. 我尽力使用LINQ Join()
但是我找不到如何使它适应我的示例的方法,我会很乐于助人,很可能答案很简单,以至于我找不到真正的答案。它。
Thank you in advance! 先感谢您!
You can use HashSet<T>.IntersectWith
: 您可以使用HashSet<T>.IntersectWith
:
HashSet<ulong> result = data.First();
foreach (HashSet<ulong> set in data.Skip(1))
result.IntersectWith(set);
Modifies the current
HashSet<T>
object to contain only elements that are present in that object and in the specified collection. 修改当前HashSet<T>
对象,使其仅包含该对象和指定集合中存在的元素。
Aggregate combined with intersect will get you the common elements that exist in all sets. 集合与相交相结合将为您提供所有集合中存在的公共元素。
var orderedData = data.ToList();
var commonSet = orderedData.Skip(1).Aggregate((IEnumerable<ulong>)(orderedData.First()), (c, n) => c.Intersect(n));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.