【问题标题】:Sort CSV data when the number of columns isn't known?当列数未知时对 CSV 数据进行排序?
【发布时间】:2021-06-26 20:43:48
【问题描述】:

考虑一个 CSV 文件,其中我知道前两列的外观,但不知道其余列的外观:

Id | DateWithTime | column 3 | ... | column n

我想读取这样一个文件,按DateWithTime 列排序并保存。我不知道文件有多少列,所以我无法为它建立模型。我只知道它至少有前两列IdDateWithTime。那么,如何使用 CSVHelper 访问该文件并对其进行排序?

注意:假设DateWithTime 可以按字母顺序排序,这里没什么特别的。问题是如何访问它,由于列数未知,我无法构建模型。

注意 2:标题可能不完整,例如标题可能有 5 列,但数据有时可能有 6 列或更多。

【问题讨论】:

    标签: c# csv csvhelper


    【解决方案1】:

    也许阅读为dynamic 对象是可行的? https://joshclose.github.io/CsvHelper/examples/reading/get-dynamic-records/

    void Main()
    {
        using (var reader = new StreamReader("path\\to\\file.csv"))
        using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
        {
            var records = csv.GetRecords<dynamic>();
            var sorted = records.OrderBy(i => DateTime.Parse(i.DateWithTime)).ToList();
    
            using (var writer = new StreamWriter("output.csv"))
            using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
            {
                csv.WriteRecords(records);
            }
        }
    }
    

    虽然“可能比标题更多的行”问题可能不适用于此。

    另一种选择可能是将数据作为行读取和排序,而不对其进行解析(尽管如果某些数据是多行,这将是有问题的)。

    【讨论】:

    • 感谢您的回复。与此同时,我的情况发生了变化,标题总是完整的。所以动态是一种选择。但是,是否可以混合使用静态类型和动态类型,例如我可以使用我对前两列 IdDateWithTime 的数据类型的了解,还是我完全必须去“动态”?
    【解决方案2】:

    也许 DataTable 会是解决方案? 您可以根据需要添加任意数量的列,插入行,保留日期时间数据类型,其余列是纯文本,这不是问题。 DataTable 可以对行进行排序。 如果标题不完整,可以在读取文件时添加一列。 或者添加比您预期更多的列。列名无关紧要。

    编辑: 可以使用以下类读取更好的选项:

    public class Row
    {
       public int Id {get;set;}
       public DateTime DateWithTime {get;set;}
       public string RestOf {get;set;}
    
    }
    

    你不关心列的长度,用 Linq 排序很容易

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-15
      • 2014-10-19
      • 2020-04-17
      • 2012-07-11
      • 1970-01-01
      • 2015-11-03
      相关资源
      最近更新 更多