List <string []>由Linq确定最大长度

Byy*_*yyo 19 c# linq list

我有以下结构

List<string[]> sList = new List<string[]>() {
    new[] { "x", "xxx", "xxxx" },  //1,3,4
    new[] { "x", "xx", "xx" },     //1,2,2
    new[] { "xxxxxx", "xx", "xx" } //6,2,2
};
Run Code Online (Sandbox Code Playgroud)

我需要string.length按列确定项目的最大值

在此示例中,预期结果应为:

List<int> Result = new List<int>() { 6, 3, 4 };
Run Code Online (Sandbox Code Playgroud)

有一个简单的Linq方法吗?

我的努力(工作但不使用Linq):

List<int> Result = new List<int>();
foreach (string[] line in Table)
{
    for (int i = 0; i < line.Length; i++)
    {
        if (Result.Count > i)
        {
            if (Result[i] < line[i].Length)
            {
                Result[i] = line[i].Length;
            }
        }
        else
        {
            Result.Insert(i, line[i].Length);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

行/列的数量是动态的,但每行的列数相同.

Tom*_*ode 21

这是我能想到的最好的:

List<int> Result = sList.First().Select((x, i) => sList.Max(y => y[i].Length)).ToList();
Run Code Online (Sandbox Code Playgroud)

一条线的奖励积分?

说明:由于您说它们都具有相同数量的元素,因此请取第一行并循环遍历该元素.使用索引从每个其他行获取该元素获取长度,然后获取最大值.

  • 谢谢,伟大的解决方案,我希望我能接受两者 - 但蒂姆的更容错 (2认同)

Tim*_*ter 19

一种方法:

int maxColumns = sList.Max(arr => arr.Length);
List<int> Result = Enumerable.Range(0, maxColumns)
    .Select(i => sList.Max(arr => (arr.ElementAtOrDefault(i) ?? "").Length))
    .ToList();
Run Code Online (Sandbox Code Playgroud)

您需要每列的最大长度.列是数组索引.所以你需要一种方法来查看每个索引的数组.所以我用过Enumerable.Range(0, maxColumns).然后我ElementAtOrDefault用来处理数组不包含这么多"列"的情况(不需要,因为我在下面解释).返回null参考类型,如string.我用null-coalescing运算符替换它们"",产生0作为长度.

既然你已经提到过"每一行都有相同的列数",那么你可以让它更具可读性:

List<int> Result = Enumerable.Range(0, sList.First().Length)
    .Select(i => sList.Max(arr => arr[i].Length))
    .ToList();
Run Code Online (Sandbox Code Playgroud)


Kob*_*obi 6

这是一种使用方法Aggregate:

var maxLengths = sList.Select(strings => strings.Select(s => s.Length))
                      .Aggregate((prev, current) => prev.Zip(current, Math.Max));
Run Code Online (Sandbox Code Playgroud)

这假设每个集合具有相同数量的项目.

这个怎么运作:

  • 首先我们只取字符串的长度,所以从概念上讲我们正在使用IEnumerable<IEnumerable<int>>,所以我们的集合看起来像这样:

    {{1, 3, 4},
     {1, 2, 2},
     {6, 2, 2}}
    
    Run Code Online (Sandbox Code Playgroud)

    (这不准确 - 由于延迟执行,我们从未实际拥有此集合 - 根据需要计算每行的长度.)

  • 接下来,我们使用Aggregate组合向量:

    • 我们有{1, 3, 4}{1, 2, 2}.
    • Zip两个集合:{{1, 2}, {3, 2}, {4, 2}}.
    • 适用Math.Max于每一对,并得到{2, 3, 4}.
  • 重复{2, 3, 4}{6, 2, 2}和接收{6, 3, 4}.

优点:

  • 适用于单行.
  • 仅迭代集合一次.
  • 不对具体实现(阵列列表)做任何假设 - 可以使用任何IEnumerable<IEnumerable<string>>,而不依赖于[i]ElementAtOrDefault.
  • 您已经要求Linq解决方案了.

缺点:

  • 有点复杂.
  • 如果行的长度不同,则Zip行为不符合预期(返回最短的长度而不是最长的长度).