先日作った「GCCS-CS1.0」ではデータをCSVファイルで管理していた。そんとき作った関数をまとめとく。「CSVが外部ファイルであるとき」と「CSVをリソース化してexeに含めてるとき」の二通りに対応する。

こんな順番で書くぜ。

  1. 改行を含むCSVファイルを用意しとく
  2. CSVをリソースに追加しとく
  3. 今回作ったCSV二次元配列化関数
  4. ついでに、作った二次元配列を確認する関数を準備
  5. 実行
  6. 結果

1. 改行を含むCSVファイルを用意しとく

0,緑色,Midori-iro,"みどりいろ"
1,うぇる,Weruda,"ウェル
ダ"

2. CSVをリソースに追加しとく

上述のCSVをテキストファイルとしてプロジェクトのリソースに追加しとく。

3. 今回作ったCSV二次元配列化関数

// CSVファイルのパスとリソースを渡す
private string[][] foo(string csv_path, string resource)
{
    // Microsoft.VisualBasicのアセンブリ参照を追加しておくこと。
    Microsoft.VisualBasic.FileIO.TextFieldParser parser;

    // CSVファイルを確認できたらそれを使い、なければリソースを使う
    if (System.IO.File.Exists(csv_path))
    {
        parser = new Microsoft.VisualBasic.FileIO.TextFieldParser(
            csv_path, Encoding.GetEncoding("UTF-8"));
    }
    else
    {
        // TextFieldParserに直接文字列を渡すときはstringじゃなく
        // StringReaderを通さないとダメ
        var reader = new System.IO.StringReader(resource);
        parser = new Microsoft.VisualBasic.FileIO.TextFieldParser(
            reader);
    }

    // 二次元配列化
    var lis = new List();
    using (parser)
    {
        // 区切り文字を指定
        parser.TextFieldType =
            Microsoft.VisualBasic.FileIO.FieldType.Delimited;
        parser.SetDelimiters(",");
        while (!parser.EndOfData)
        {
            string[] row = parser.ReadFields();
            var lis_row = new List();
            foreach (string r in row)
            {
                lis_row.Add(r);
            }
            lis.Add(lis_row.ToArray());
        }
    }
    return lis.ToArray();
}

4. ついでに、作った二次元配列を確認する関数を準備

private void print_2D_array(string[][] array)
{
    for (int i = 0; i < array.Length; i++)
    {
        string format = string.Format("[{0}] => [\r\n", i);
        for (int j = 0; j < array[i].Length; j++)
        {
            format += string.Format("    [{0}] => {1},\r\n", j, array[i][j]);
        }
        format += "],";
        Console.WriteLine(format);
    }
}

5. 実行

string[][] a = foo(@"C:\Users\Midoriiro\Desktop\しーえすぶい.csv",
    Properties.Resources.しーえすぶい);
print_2D_array(a);

6. 結果

[0] => [
    [0] => 0,
    [1] => 緑色,
    [2] => Midori-iro,
    [3] => みどりいろ,
],
[1] => [
    [0] => 1,
    [1] => うぇる,
    [2] => Weruda,
    [3] => ウェル
ダ,
],
改行もちゃんと含まれてるぜ!

最初は静的型付けメチャメチャ面倒くせーな! と思ってたのだけど、書いてるうちに楽しくなってきたよ。特に、引数と返り値の型が普遍的だってのは不便な反面安心感があるよね。