Create array of string on every nth element
Updated: Parsing a CSV file
It looks like the actual question is how to parse a CSV file into records.
A crude approach would be to read the file one line at a time and split that line:
var lines=File.ReadLines(path);
foreach(var line in lines)
{
var parts=line.Split(",");
}
ReadLines
returns an IEnumerable<string>
that returns one line at a time instead of reading and splitting the entire file at once.
This code can be converted to a LINQ query, and even be used to construct records:
var records= File.ReadLines(path)
.Select(line=>line.Split(","))
.Select(b=>new SomeRecord(b[0],b[1],b[2],b[3],b[4]))
.ToArray();
This code won't trim the surrounding quotes. To do that, one would have to use Trim('"')
, eg b[0].Trim('"')
. That's not the most elegant solution.
If the file is retrieved as a single string through an API, a StringReader can be used to read it line by line, eg:
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();
Another possibility would be to use a regex to both split and trim, but a better solution would be to use a CSV parsing library like CsvHelper, that can handle all the quirks in a CSF file, like quoted fields, newlines in fields and even missing fields
Original answer
The result shows batching the array elements in batches of 5 items, not accessing every nth element. Batching in LINQ is possible using Chunk in .NET (Core) 6 and later. In older versions you can use MoreLINQ's Batch.
In .NET 6, you can use :
var batches=elements.Chunk(5);
batches
is an IEnumerable<string[]>
. You can convert them to an array with ToArray
or you can use Select
to construct objects from the batch items, eg :
var records=elements.Chunk(5)
.Select(b=>new SomeRecord(b[0],b[1],b[2],b[3],b[4]))
.ToArray();
MoreLinq's Batch
returns an IEnumerable<IEnumerable<T>>
. This avoids allocating a new array for every batch. If you need to handle the items as an array though, you'd need an extra 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();