CsvHelperでのcsv読み込みを、Genericsを使って汎用化


C#でcsvを読み込む時に、使いやすいのがCsvHelperというモジュール。
以前、CsvHelperの備忘録を書いたのですが、汎用的でなかったので、改善

以前の記事

CsvHelper覚え書き

今回は、有名なIrisデータセットの読み込み例

CsvHelperで、csvのListを作るには、

  • csvのカラム情報をもったクラスを作ること
class Iris
{
    public double SepalLength { get; set; }
    public double SepalWidth { get; set; }
    public double PetalLength { get; set; }
    public double PetalWidth { get; set; }
    public string Species { get; set; }
}
  • CsvHelper.Configuration.CsvClassMap<Iris>を継承したマッピングクラスを作ること
class CreateMap : CsvHelper.Configuration.CsvClassMap<Iris>
{
    public CreateMap()
    {
        Map(x => x.SepalLength).Index(0);
        Map(x => x.SepalWidth).Index(1);
        Map(x => x.PetalLength).Index(2);
        Map(x => x.PetalWidth).Index(3);
        Map(x => x.Species).Index(4);
    }
}

が条件だった。これを、汎用的に読み込むために、ジェネリクスを使って関数化する。

/// <summary>
/// Reads the csv.
/// </summary>
/// <returns>The csv.</returns>
/// <param name="filename">ファイル名</param>
/// <typeparam name="T">CSVのカラム情報.</typeparam>
/// <typeparam name="M">Mapper</typeparam>
public static List<T> ReadCsv<T, M>(string filename) where M: CsvHelper.Configuration.CsvClassMap<T>
{
    using (var parse = new CsvHelper.CsvReader(new StreamReader(filename)))
    {
        parse.Configuration.HasHeaderRecord = false;
        parse.Configuration.RegisterClassMap<M>();
        List<T> data = parse.GetRecords<T>().ToList();
        return data;
    }
}

こうすることで、TMに型を指定するだけで、様々なcsvファイルの読み込みが可能となる