使用 Linq C# 将锯齿状列表<List<String>> 转置为矩形列表

Transpose a Jagged List<List<String>> to a Rectangular One Using Linq C#

我的问题与此处的问题非常相似:

除了我对解决方案的测试让我注意到它在偶数阵列上效果最好,而不是在不均匀阵列上。出于好奇,我从上面 link 中获取的公认解决方案和其他一些解决方案都产生了转置,而没有填充锯齿状列表中缺乏信息的情况。

{{"a"},
 {"b","c"}} 

将转置为

{{"a","b"},
 {"c"}} 

而不是

{{"a","b"},
 {null,"c"}}.

我的源数据可能没有任何内容,例如,在将成为列表的内容末尾的三个空白信息位置,它会被截断而没有任何空值。当我转置时,我希望能够在源数据中不是最长长度的列表中插入空值或其他一些特定值。我知道仅使用标准 for 循环来处理它的最佳方法,但我想要一个使用 Linq 的解决方案,不幸的是我不太熟悉。

如有任何帮助,我们将不胜感激!

好吧,如果我们想转置锯齿状的集合,例如

  var source = new string[][] {
    new string[] {"a", "b", "c"},
    new string[] {"d"},
    new string[] {"e", "f"},
    new string[] {"g", "h", "i", "j"},
  };

我们可以计算 columns 的数量:我输入了 .Count() 所以 List<List<string>>string[][] 都可以。

  int columns = source.Max(line => null == line ? 0 : line.Count());

然后如果我们想排除 nulls 过滤掉没有所需项目数的行:

  // Change .ToArray() to .ToList() if you want to have jagged List
  var result = Enumerable
    .Range(0, columns)
    .Select(c => source
       .Where(line => line != null && line.Count() > c)
       .Select(line => line[c])
       .ToArray())
    .ToArray();

一起来看看:

  string report = string.Join(Environment.NewLine, result
    .Select(line => string.Join(" ", line.Select(c => c ?? "-"))));

  Console.Write(report);

结果:

a d e g
b f h
c i
j

请注意,用 nulls 转置空洞将是

var result = Enumerable
  .Range(0, columns)
  .Select(c => source
     .Select(line => line == null || line.Count() <= c ? null : line[c])
     .ToArray())
  .ToArray();

结果:

a d e g
b - f h
c - - i
- - - j