0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

メモ

Posted at

CSV分割・変換ツール 設計書

概要

このツールは、コマンドライン引数で指定されたCSVファイルを4つの出力ファイルに分割し、各ファイルごとに異なる変換仕様に従って出力する。変換内容には単純な値変換、固定値出力、条件付きスキップ、2段階抽出などが含まれる。


📁 クラス構成

├── Program.cs             // エントリポイント
├── CsvRow.cs              // 1行分のCSVデータ表現(ラッパー)
├── CsvLoader.cs           // CSV読み込みロジック
├── CsvSplitter.cs         // 各ファイル向けの抽出処理
├── Converter.cs           // 値の変換処理
├── Extractor.cs           // ファイルごとの行抽出処理
└── Writer.cs              // 分割後CSVの出力処理

🧩 クラス詳細

CsvRow.cs

public class CsvRow
{
    private readonly List<string> _columns;

    public CsvRow(List<string> columns)
    {
        _columns = columns;
    }

    public string this[int index] => index < _columns.Count ? _columns[index] : "";

    public List<string> Columns => _columns;
}

CsvLoader.cs

public static class CsvLoader
{
    public static List<CsvRow> Load(string path)
    {
        var rows = new List<CsvRow>();
        foreach (var line in File.ReadLines(path))
        {
            var columns = line.Split(',').ToList();
            rows.Add(new CsvRow(columns));
        }
        return rows;
    }
}

CsvSplitter.cs

public static class CsvSplitter
{
    public static Dictionary<string, List<CsvRow>> Split(List<CsvRow> rows, List<Func<CsvRow, CsvRow>> extractors, List<string> fileNames)
    {
        var result = new Dictionary<string, List<CsvRow>>();
        for (int i = 0; i < extractors.Count; i++)
        {
            result[fileNames[i]] = new List<CsvRow>();
        }

        foreach (var row in rows)
        {
            for (int i = 0; i < extractors.Count; i++)
            {
                var extracted = extractors[i](row);
                if (extracted != null)
                {
                    result[fileNames[i]].Add(extracted);
                }
            }
        }

        return result;
    }
}

Converter.cs(変換ロジック)

public static class Converter
{
    private static readonly Dictionary<string, Dictionary<string, string>> _conversionRules = new()
    {
        { "code1", new Dictionary<string, string> { { "1", "02" }, { "2", "05" } } },
        { "multi_code", new Dictionary<string, string>
            {
                { "3", "103" },
                { "8", "108" },
                { "10", "1055" }
            }
        },
        { "code101", new Dictionary<string, string> { { "3", "555" }, { "6", "777" } } }
    };

    public static string? Convert(string ruleKey, string input)
    {
        if (ruleKey == "code101" && input == "0")
            return null;

        if (_conversionRules.ContainsKey(ruleKey) && _conversionRules[ruleKey].ContainsKey(input))
        {
            return _conversionRules[ruleKey][input];
        }

        return null;
    }

    public static List<string> ConvertAndExpandMultiple(string ruleKey, string input, string fixedValueAfterEach = "01")
    {
        var results = new List<string>();

        if (string.IsNullOrWhiteSpace(input))
        {
            return results;
        }

        string[] values = input.Split(',');

        foreach (string raw in values)
        {
            string val = raw.Trim();

            if (val == "0" || val == "")
            {
                continue;
            }

            if (_conversionRules.ContainsKey(ruleKey) && _conversionRules[ruleKey].ContainsKey(val))
            {
                string converted = _conversionRules[ruleKey][val];
                results.Add(converted);
                results.Add(fixedValueAfterEach);
            }
        }

        return results;
    }
}

Extractor.cs(抽出ロジック)

public static class Extractor
{
    public static CsvRow File1Extractor(CsvRow row)
    {
        var newColumns = new List<string>();

        newColumns.Add(row[0]); // 識別ID
        newColumns.Add("01");   // 固定値

        string? converted = Converter.Convert("code101", row[101]);
        if (converted != null)
        {
            newColumns.Add(converted);
        }

        var expanded = Converter.ConvertAndExpandMultiple("multi_code", row[2]);
        foreach (var item in expanded)
        {
            newColumns.Add(item);
        }

        return new CsvRow(newColumns);
    }
}

Writer.cs

public static class Writer
{
    public static void WriteCsv(string path, List<CsvRow> rows)
    {
        using var writer = new StreamWriter(path);
        foreach (var row in rows)
        {
            writer.WriteLine(string.Join(",", row.Columns));
        }
    }
}

Program.cs(エントリーポイント)

class Program
{
    static void Main(string[] args)
    {
        if (args.Length < 1)
        {
            Console.WriteLine("Usage: CsvTool <input_file>");
            return;
        }

        string inputPath = args[0];
        var rows = CsvLoader.Load(inputPath);

        var extractors = new List<Func<CsvRow, CsvRow>>
        {
            Extractor.File1Extractor,
            // Extractor.File2Extractor,
            // Extractor.File3Extractor,
            // Extractor.File4Extractor
        };

        var fileNames = new List<string>
        {
            "file1.csv",
            "file2.csv",
            "file3.csv",
            "file4.csv"
        };

        var splitted = CsvSplitter.Split(rows, extractors, fileNames);

        foreach (var kvp in splitted)
        {
            Writer.WriteCsv(kvp.Key, kvp.Value);
        }
    }
}

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?