【问题标题】:C# LINQ "inner join" of collections集合的 C# LINQ“内部连接”
【发布时间】:2017-06-23 09:54:47
【问题描述】:

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

我正在尝试尽可能优雅地编写代码,我想知道是否有一些 LINQ 技巧可以做到这一点,最好是单行。如果有帮助,IEnumerables 都是 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() 但我不知道如何使其适应我的示例,我会很感激你的帮助,很可能答案很简单,我真的找不到它。

提前谢谢你!

【问题讨论】:

  • 是的,我意识到我错了,我已经删除了那条评论。

标签: c# .net linq collections lambda


【解决方案1】:

你可以使用HashSet&lt;T&gt;.IntersectWith:

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

修改当前的HashSet&lt;T&gt; 对象以仅包含以下元素 存在于该对象和指定的集合中。

【讨论】:

  • 很有趣,我知道IntersectWith(),但由于某种原因,我没有想到这么明显的解决方案......我选择它作为最佳答案,因为它枚举了data 远少于其他(仍然有效的)LINQ 建议,非常感谢!
【解决方案2】:

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

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

【讨论】:

  • 这个也能正常工作,很好地解决了我的问题,所以我也赞成它。非常感谢!
【解决方案3】:

试试这个:

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

MSDN

【讨论】:

  • 我现在真的很好奇哪个性能最好... :)
  • 如果我没有HashSet 给我的IntersectWith() 的魔力,这将是我的首选,如果您的初始数据不是IEnumerable&lt;HashSet&lt;T&gt;&gt;,我建议使用它,我想它适用于所有情况,如果有人不想使用 HashSet,那么他可以添加 Distinct(),感谢提供好的 Linq 解决方案!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多