一尘不染

多个列表与IEnumerable.Intersect()的交集

c#

我有一个列表列表,我想像这样找到交集:

var list1 = new List<int>() { 1, 2, 3 };
var list2 = new List<int>() { 2, 3, 4 };
var list3 = new List<int>() { 3, 4, 5 };
var listOfLists = new List<List<int>>() { list1, list2, list3 };

// expected intersection is List<int>() { 3 };

有没有办法用IEnumerable.Intersect()做到这一点?

编辑:我应该对此更加清楚:我确实有一个列表列表,我不知道会有多少列表,上面的三个列表只是一个例子,我实际上是
IEnumerable<IEnumerable<SomeClass>>

感谢您提供的所有出色答案。事实证明,有四个选项可以解决此问题: List + aggregate (@Marcel Gosselin),
List + foreach (@ JaredPar,@ Gabe Moothart), HashSet + aggregate
(@jesperll)和 HashSet + foreach (@Tony the Pony)。我做了这些解决方案的一些性能测试(不同
列表的数量元素的数量 在每个列表和 随机数最大 尺寸。

事实证明,在大多数情况下,HashSet的性能都优于List(我猜想是因为HashSet的性质,大列表和较小的随机数大小除外)。方法(foreach方法的性能
稍好 一些。)

对我来说,聚合方法确实很吸引人(我将其作为公认的答案),但我不会说这是最易读的解决方案。再次感谢大家!


阅读 285

收藏
2020-05-19

共1个答案

一尘不染

怎么样:

var intersection = listOfLists
    .Skip(1)
    .Aggregate(
        new HashSet<T>(listOfLists.First()),
        (h, e) => { h.IntersectWith(e); return h; }
    );

这样,就可以通过始终使用同一HashSet并在单个语句中对其进行优化。只要确保listOfLists始终包含至少一个列表即可。

2020-05-19