【问题标题】:CSV to Dictionary, matching up column titles and row values?CSV 到字典,匹配列标题和行值?
【发布时间】:2025-12-17 03:20:05
【问题描述】:

问这个我觉得很尴尬,但我根本无法得到我想要的结果。

我有一个如下所示的 CSV 文件:

Col_Title_1|Col_Title_2|Col_Title_3|Col_Title_4|Col_Title_5
  Value_1  |  Value_2  |  Value_3  |  Value_4  |  Value_5

我想读取这些数据并对其进行操作,例如(伪代码):

var test = array.Column("Col_Title_3").Value;

我似乎无法将列配对并相应地增加值。

最好使用字典或 KeyValuePair 吗?

这是我做过的 1 个很好的测试,但当然不能 100% 工作:

Dictionary<string, string> dict = File.ReadLines(e.FullPath).Select(line =>
line.Split('|')).ToDictionary(line => line[0], line => line[1]);

我知道我可以像这样使用 hacky/hard code 方式:

string lineValues = File.ReadLines(e.FullPath).ElementAt(1);
string row3 = lineValues.Split('|')[2];
string row5 = lineValues.Split('|')[4];

但出于显而易见的原因,我不想这样做。

任何帮助将不胜感激!谢谢大家!

【问题讨论】:

  • 我认为@Rene147 的解决方案是最好的。创建一个与您想要的匹配的 POCO,然后使用帮助程序类根据工作表为您提供 POCO 列表。 KeyValuePair 或 Dictionary 都不是好的选择,尤其是 Dictionary 因为您要为电子表格中的每一行覆盖字典中的值。

标签: c# csv dictionary keyvaluepair


【解决方案1】:

你可以这样做。

var lines = File.ReadLines("test.txt");
var header  = lines.First().Split('|');
var data = lines.Skip(1).First().Split('|');
var dict = new Dictionary<string, string>();
for (int i = 0; i < header.Length; i++)
{
    dict.Add(header[i], data[i]);
}

Console.WriteLine("Taking Col_Title_3 -> {0}", dict["Col_Title_3"]);
foreach (var i in dict.Keys)
{
    Console.WriteLine("key: {0} value: {1}",i,dict[i]);
}

或者字典也可以像这样填充

var lines = File.ReadLines("test.txt");
var header = lines.First().Split('|');
var data = lines.Skip(1).First().Split('|');            
var dict = header.Select((a, i) => new { key = a, data = data[i] })
              .ToDictionary(b => b.key, c => c.data);

【讨论】:

  • 非常感谢库努克!有趣的是,我在您发布前几分钟解决了我自己的问题,但我尝试了您的解决方案并且性能更好 - 再次感谢:)。
【解决方案2】:

如果您可以使用第三方库,我强烈建议您查看CSVHelper(您可以使用 nuget 将其添加到您的项目中)。您可以只创建一个 POCO(普通旧 CLR 对象)来定义您要映射的列,其余的由它完成。会让这变得容易得多。

【讨论】:

    【解决方案3】:

    实现示例

    class Program
    {
        static void Main(string[] args)
        {
            string[] lines = new string[] {
                "Col_Title_1|Col_Title_2|Col_Title_3|Col_Title_4|Col_Title_5", //Line 0 is Header/Columns
                "Value_1|Value_2|Value_3|Value_4|Value_5" //Line 1 and so on is data records
            };
            string fileContent = "Col_Title_1|Col_Title_2|Col_Title_3|Col_Title_4|Col_Title_5" + Environment.NewLine +
                          "Value_1|Value_2|Value_3|Value_4|Value_5";
            CSVTable table = new CSVTable(lines);
            string firstColumnvalue = table[0]["Col_Title_1"];
            Console.WriteLine(firstColumnvalue);
            table = new CSVTable(fileContent);
            firstColumnvalue = table[0]["Col_Title_1"];
            Console.WriteLine(firstColumnvalue);
    
        }
    }
    
    public class CSVTable
    {
        public CSVTable(string table)
            : this(table.Split(new string[] { Environment.NewLine }, StringSplitOptions.None))
        {
        }
    
        public CSVTable(string[] lines)
        {
            Columns = lines[0].Split('|');
            Records = lines.ToList().GetRange(1, lines.Length - 1).Select(line => new CSVRecord(line, Columns)).ToList();
        }
        public string[] Columns { get; private set; }
        List<CSVRecord> Records { get; set; }
    
        public CSVRecord this[int index]
        {
            get { return Records[index]; }
        }
    }
    
    public class CSVRecord : Dictionary<string, string>
    {
        public CSVRecord(string line, string[] keys)
            : base()
        {
            var lista = line.Split('|');
            for (int i = 0; i < lista.Length; i++)
            {
                Add(keys[i], lista[i]);
            }
        }
    }
    

    【讨论】: