基本上我有一个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()
,但我无法找到如何使它适应我的例子,我很感激有用的手,很可能答案是如此简单,我不能真的找到它。
提前谢谢!
答案 0 :(得分:2)
您可以使用HashSet<T>.IntersectWith
:
Card
修改当前
... public Deck(){ for(int i = 0; i < CARD_SET; i++){ Card card = new Card(); if( i >= 0 && i < NUM_FACE) { card.setSuite("club"); card.setFace(i + 1); ...
对象以仅包含其中的元素 存在于该对象和指定的集合中。
答案 1 :(得分:1)
与intersect结合使用的聚合将为您提供所有集合中存在的公共元素。
var orderedData = data.ToList();
var commonSet = orderedData.Skip(1).Aggregate((IEnumerable<ulong>)(orderedData.First()), (c, n) => c.Intersect(n));
答案 2 :(得分:1)
试试这个:
var result = new HashSet<ulong>(
data.SelectMany(x => x).Where(x => data.All(z => z.Contains(x)))
);
请参阅MSDN