Linq中如何将IEnumerable<IEnumerable<T>>拼接为单个扁平IEnumerable?
如何用LINQ将多个IEnumerable序列扁平化为单一序列?
嘿,这个问题我太熟了!其实LINQ里有个专门干这事的利器,比反复调用Concat方便多了,给你几种实用的解决方法:
1. 首选:用SelectMany直接展平(最简洁高效)
如果你的数据源本身就是一个包含多个子序列的序列(比如IEnumerable<IEnumerable<T>>),直接调用SelectMany就能一键展平。它的作用就是遍历外层序列的每个子序列,把所有子序列里的元素都“拉”到同一个扁平序列里。
举个代码例子:
// 假设你有一堆嵌套的整数序列 var nestedSequences = new List<IEnumerable<int>> { Enumerable.Range(1, 3), // 1,2,3 Enumerable.Range(4, 2), // 4,5 Enumerable.Range(6, 4) // 6,7,8,9 }; // 一行代码完成展平 var flattenedSequence = nestedSequences.SelectMany(subSequence => subSequence); // 输出结果就是:1,2,3,4,5,6,7,8,9
如果你的序列是零散的(比如单独的seq1、seq2、seq3),也可以先把它们打包成一个集合,再用SelectMany:
var seq1 = Enumerable.Range(1,3); var seq2 = Enumerable.Range(4,2); var seq3 = Enumerable.Range(6,4); var flattened = new[] { seq1, seq2, seq3 }.SelectMany(x => x);
2. 查询表达式风格的写法(和SelectMany等价)
如果你习惯用LINQ的查询表达式语法,也可以用嵌套的from语句,本质上和SelectMany是完全一样的,只是写法不同:
var flattenedSequence = from outerSequence in nestedSequences from item in outerSequence select item;
3. 多次调用Concat(适合少量序列的场景)
如果你的序列数量很少,也可以用Enumerable.Empty<T>()作为起点,多次拼接。不过这种方法在序列多的时候会生成多个中间序列,性能不如SelectMany,所以只推荐在序列数量极少的情况下用:
var flattened = Enumerable.Empty<int>() .Concat(seq1) .Concat(seq2) .Concat(seq3);
总结一下,SelectMany是处理这种多序列展平场景的最优解,代码简洁、性能高效,不管是嵌套序列还是零散序列都能轻松搞定。
内容的提问来源于stack exchange,提问作者Robert Sim
相关产品推荐
相关产品推荐

