C# 如何实现嵌套列表同索引元素的分组重组
C# 实现嵌套列表同索引元素归集(转置)
你需要的效果本质是二维嵌套序列的行列转置,以下是两种生产环境可用的实现方案:
方案1:LINQ 通用实现(适配绝大多数场景)
引入System.Linq命名空间后,可直接通过拍平-分组的逻辑实现转置,兼容子列表长度不一致的场景,不会触发索引越界问题:
// 模拟输入的嵌套列表 var originalNestedList = new List<List<string>> { new() { "a", "b", "c" }, new() { "m", "n", "o" }, new() { "x", "y", "z" } }; // 核心转置逻辑 var transposedList = originalNestedList .SelectMany(inner => inner.Select((value, index) => new { value, index })) .GroupBy(item => item.index) .Select(group => group.Select(x => x.value).ToList()) .ToList();
代码逻辑拆解:
- 将所有子列表的元素连带自身在子列表内的索引位置,拍平成带索引的临时对象集合
- 按照索引值对临时集合分组
- 每个分组内的元素,就是原嵌套列表中处于相同索引位置的所有值,转为列表即为目标结果
方案2:手动循环实现(适配高性能/无LINQ依赖场景)
如果场景对性能要求较高,或是在不支持LINQ的老版本.NET环境下,可通过双层循环手动归集元素:
var transposedList = new List<List<string>>(); // 计算所有子列表的最大长度,确定新列表的总数量 int maxInnerCount = originalNestedList.Max(l => l.Count); for (int colIndex = 0; colIndex < maxInnerCount; colIndex++) { var currentColumn = new List<string>(); // 逐行取对应索引的元素 foreach (var innerList in originalNestedList) { // 跳过短子列表的越界索引 if (colIndex < innerList.Count) { currentColumn.Add(innerList[colIndex]); } } transposedList.Add(currentColumn); }
效果验证
上述两种方案针对示例输入,最终得到的transposedList与预期完全一致:
- 第1个新列表:
["a", "m", "x"]- 第2个新列表:
["b", "n", "y"]- 第3个新列表:
["c", "o", "z"]
通用适配提示
- 处理其他数据类型的嵌套列表时,只需将代码中的泛型类型
string替换为目标类型即可,逻辑完全通用 - 若原嵌套列表可能为空集合,在调用
Max方法前需先做空判断,避免触发空集合取最大值的异常 - 若确定所有子列表长度完全一致,也可使用
Zip链式写法简化代码,但遇到长度不一致的子列表时会提前截断,不建议作为通用方案使用
内容的提问来源于stack exchange,提问作者Abdullahi
相关产品推荐
相关产品推荐

