在 CsvHelper 中使用多种记录类型将记录分组在一起

Grouping records together using multiple record types in CsvHelper

我有一个很大的日志文件,其中包含我要解析的不同记录类型。它看起来像这样:

$L,8,PO
$L,8,SF
$P,8,P,0,102,0,19:08:34.463
$P,9,P,0,110,0,19:08:34.460
$P,8,P,0,105,0,19:08:34.407
$L,8,SF
$P,9,A,0,139,0,19:08:34.374
$P,15,P,0,103,0,19:08:34.532
$P,8,P,0,73,0,19:08:34.436
$L,8,SF
$L,8,PI

我目前正在使用 CsvHelper 并遵循 this example 如何使用 switch 语句读取多个记录类型。但是我有点卡住了,因为我想根据 $L 记录中包含的值对 $P 记录进行分组,然后将输出写入单独的 CSV 文件。

例如,第一个和最后一个 $L 记录都在第二个字段中包含一个 8,加上 PO/PI 消息(这将是我的文件的 start/end 所有 $P 记录包含8 在第二个字段中)。 8.csv 的文件输出如下所示:

$P,8,P,0,102,0,19:08:34.463
$P,8,P,0,105,0,19:08:34.407
$P,8,P,0,73,0,19:08:34.436

除了以这种方式将它们组合在一起之外,我还想根据包含 SF 和数字 8 的 $L 消息在 $P 记录之前添加一个数字。上面有 3 条 SF 消息包含 SF 和8,所以最终文件看起来像这样:

1,$P,8,P,0,102,0,19:08:34.463
1,$P,8,P,0,105,0,19:08:34.407
2,$P,8,P,0,73,0,19:08:34.436

完成此任务的最佳方法是什么?目前,我正在将所有包含相同 ID 号的 $P 消息添加到键值对为:List<$P Record> 的字典中,我不太确定如何根据这些值对 $P 记录进行分组另一条记录。

尝试这样的事情。向记录添加行然后对记录进行分组更容易。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;


namespace ConsoleApplication184
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.txt";
        static void Main(string[] args)
        {
            int count = 0;
            string line = "";
            StreamReader reader = new StreamReader(FILENAME);
            List<Record> records = new List<Record>();
            while ((line = reader.ReadLine()) != null)
            {
                int startComment = line.IndexOf("//");
                if (startComment >= 0)
                {
                    line = line.Substring(0, startComment);
                }
                line = line.Trim();
                string[] splitArray = line.Split(new char[] { ',' }).ToArray();
                Record newRecord = new Record();
                newRecord.car = int.Parse(splitArray[1]);
                newRecord.type = (Record.RECORD_TYPE)Enum.Parse(typeof(Record.RECORD_TYPE), splitArray[2]);
                records.Add(newRecord);

                switch (splitArray[0])
                {
                    case "$P":
                        newRecord.message = line;
                        break;
                }
            }

            var cars = records.GroupBy(x => x.car);

            foreach (var car in cars)
            {
                int lap = 0;
                int stint = 0;

                foreach (Record record in car)
                {
                    record.lap = lap;
                    record.stint = stint;
                    switch (record.type)
                    {
                        case Record.RECORD_TYPE.SF:
                            record.lap = ++lap;
                            break;
                        case Record.RECORD_TYPE.P:
                            string output = string.Join(",", new string[] { record.stint.ToString(), record.lap.ToString(), record.message });
                            Console.WriteLine(output);
                            break;
                        case Record.RECORD_TYPE.PO :
                            record.stint = ++stint;
                            break;
                    }
                }
            }

            Console.ReadLine();
        }

    }
    public class Record
    {
        public enum RECORD_TYPE
        {
            PO,
            SF,
            P,
            PI,
            A
        }
        public RECORD_TYPE type { get; set; }
        public int stint { get; set; }
        public int lap { get; set; }
        public int car { get; set; }
        public string message { get; set; }
    }
}