读取 CSV 行/记录的重复子部分?

Reading repetitive sub-sections of a CSV line / record?

在CSVHelper中,是否可以从源CSV文件的一行中读取重复的子记录?

我正在使用的 CSV 格式包含如下部分:

(所有这些文本都是 CSV 文件的单行)

TYPICAL/EXTREME PERIODS,6,
Summer - Week Nearest Max Temperature For Period,Extreme,7/13,7/19,
Summer - Week Nearest Average Temperature For Period,Typical,6/22,6/28,
Winter - Week Nearest Min Temperature For Period,
Extreme,1/20,1/26,Winter - Week Nearest Average Temperature For Period,Typical,12/ 8,12/14,
Autumn - Week Nearest Average Temperature For Period,Typical,10/ 6,10/12,
Spring - Week Nearest Average Temperature For Period,Typical,4/26,5/ 2

第一个字段TYPICAL...只是一个常量标记。

第二个字段6表示会有多少条重复的子记录

因此下面的6块字段每块都有相同的格式,每块4个字段。我想将这 6 个部分中的每一个都读取/映射到一个单独的 class 对象,每个对象都具有相同的类型。


我在 documentation 中看到有很多方法可以解析数据,但 none 似乎完全符合这一点。可以将给定行/记录上的所有字段读取为可枚举的值列表(或动态大小的 dynamic 对象),但这些方法失去了 CSVHelper 的大部分优势,即它可以映射数据给你一个对象。

不幸的是,我不认为有一个好的方法可以为您的示例使用 CsvHelper 的所有映射功能,但是手动构建对象会相当容易。

public class Program
{
    public static void Main(string[] args)
    {
        using (MemoryStream stream = new MemoryStream())
        using (StreamWriter writer = new StreamWriter(stream))
        using (StreamReader reader = new StreamReader(stream))
        using (CsvReader csv = new CsvReader(reader, CultureInfo.InvariantCulture))
        {
            writer.WriteLine("TYPICAL/EXTREME PERIODS,6,Summer - Week Nearest Max Temperature For Period,Extreme,7/13,7/19,Summer - Week Nearest Average Temperature For Period,Typical,6/22,6/28,Winter - Week Nearest Min Temperature For Period,Extreme,1/20,1/26,Winter - Week Nearest Average Temperature For Period,Typical,12/ 8,12/14,Autumn - Week Nearest Average Temperature For Period,Typical,10/ 6,10/12,Spring - Week Nearest Average Temperature For Period,Typical,4/26,5/ 2");
            writer.Flush();
            stream.Position = 0;

            csv.Configuration.HasHeaderRecord = false;

            csv.Read();

            List<Foo> result = new List<Foo>();
            var rows = csv.GetField<int>(1);
            var index = 2;

            for (int i = 0; i < rows; i++)
            {
                var foo = new Foo
                {
                    Description = csv.GetField<string>(index),
                    Type = csv.GetField<string>(index + 1),
                    Start = csv.GetField<string>(index + 2),
                    End = csv.GetField<string>(index + 3)
                };

                result.Add(foo);
                index += 4;
            }
        }
    }
}

public class Foo
{
    public string Description { get; set; }
    public string Type { get; set; }
    public string Start { get; set; }
    public string End { get; set; }
}