在每个第 n 个元素上创建字符串数组

Create array of string on every nth element

我有一个string[]喜欢:

{"DNSD90OOP","234","TEST","","32324" "ASERT89UY","567","TEST2","","1256" 
"MSEWQ89UY","507","TEST3","","1206"}

我希望得到这样的结果:

{"DNSD90OOP","234","TEST","","32324"},
{"ASERT89UY","567","TEST2","","1256"},
{"MSEWQ89UY","507","TEST3","","1206"}

如何在 C# 中使用 LINQ 或仅使用 C# 来实现?

更新:解析 CSV 文件

看起来真正的问题是如何将 CSV 文件解析为记录。

一种粗略的方法是一次读取文件一行并将该行拆分:

var lines=File.ReadLines(path);
foreach(var line in lines)
{
    var parts=line.Split(",");
}

ReadLines returns IEnumerable<string> 一次 returns 一行而不是一次读取和拆分整个文件。

此代码可转换为 LINQ 查询,甚至可用于构建记录:

var records= File.ReadLines(path)
                 .Select(line=>line.Split(","))
                 .Select(b=>new SomeRecord(b[0],b[1],b[2],b[3],b[4]))
                 .ToArray();

此代码不会 trim 周围的引号。为此,必须使用 Trim('"'),例如 b[0].Trim('"')。这不是最优雅的解决方案。

如果通过 API 将文件作为单个字符串检索,则可以使用 StringReader 逐行读取它,例如:

public static IEnumerable<string> ReadStringLines(string input)
{
    using var reader=new StringReader(input);
    while(true)
    {
        var line=reader.ReadLine();
        if(line!=null)
        {
            yield return line;
        }
        else
        {
            break;
        }
    }
}

...

var records= MyUtils.ReadStringLines(input)
                 .Select(line=>line.Split(","))
                 .Select(b=>new SomeRecord(b[0],b[1],b[2],b[3],b[4]))
                 .ToArray();

另一种可能性是使用正则表达式来拆分和trim,但是更好的解决方案是使用像 CsvHelper 这样的 CSV 解析库,它可以处理 CSF 文件中的所有怪癖,例如引用字段、字段中的换行符甚至缺失字段

原回答

结果显示以 5 个项目为一组对数组元素进行批处理,而不是访问每个第 n 个元素。使用 Chunk in .NET (Core) 6 and later. In older versions you can use MoreLINQ's Batch.

可以在 LINQ 中进行批处理

.NET 6中,你可以使用:

var batches=elements.Chunk(5);

batches 是一个 IEnumerable<string[]>。您可以使用 ToArray 将它们转换为数组,或者您可以使用 Select 从批处理项目构造对象,例如:

var records=elements.Chunk(5)
                    .Select(b=>new SomeRecord(b[0],b[1],b[2],b[3],b[4]))
                    .ToArray();

MoreLinqBatch returns 和 IEnumerable<IEnumerable<T>>。这避免了为每个批次分配一个新数组。如果您需要将项目作为数组处理,则需要额外的 ToArray().

var records=elements.Batch(5)
                    .Select(batch=>{
                        var b=batch.ToArray();
                        return new SomeRecord(b[0],b[1],b[2],b[3],b[4]);
                    })
                    .ToArray();