将CSV读取到对象列表

use*_*571 29 c# csv

我有一个CSV文件,其中包含各种数据列表(日期时间,小数).来自CSV的示例行:

Date,Open,High,Low,Close,Volume,Adj Close  //I need to skip this first line as well
2012-11-01,77.60,78.12,77.37,78.05,186200,78.05
Run Code Online (Sandbox Code Playgroud)

我有一个创建的对象列表,我想读取每一行.对象的构造函数如下所示,每个CSV行的每个字段都在此处使用和分配.

    public DailyValues(DateTime date, decimal open, decimal high, decimal low,
        decimal close, decimal volume, decimal adjClose)
        : this()
    {
        Date = date;
        Open = open;
        High = high;
        Low = low;
        Close = close;
        Volume = volume;
        AdjClose = adjClose;
    }

    List<DailyValues> values = new List<DailyValues>();
Run Code Online (Sandbox Code Playgroud)

有没有一种简单的方法可以将CSV的每一行读入我的列表values并适当地分配每个属性(即日期,开放,高)?

gro*_*sNL 80

为什么不明确解析这些?您的房产数量有限,因此并不是很困难.我没有使用需要很多参数的构造函数,而是使用了一个静态方法,它返回一个新DailyValues实例作为返回类型.这类似于DateTime.FromBinary

using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;

namespace CsvDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            List<DailyValues> values = File.ReadAllLines("C:\\Users\\Josh\\Sample.csv")
                                           .Skip(1)
                                           .Select(v => DailyValues.FromCsv(v))
                                           .ToList();
        }
    }

    class DailyValues
    {
        DateTime Date;
        decimal Open;
        decimal High;
        decimal Low;
        decimal Close;
        decimal Volume;
        decimal AdjClose;

        public static DailyValues FromCsv(string csvLine)
        {
            string[] values = csvLine.Split(',');
            DailyValues dailyValues = new DailyValues();
            dailyValues.Date = Convert.ToDateTime(values[0]);
            dailyValues.Open = Convert.ToDecimal(values[1]);
            dailyValues.High = Convert.ToDecimal(values[2]);
            dailyValues.Low = Convert.ToDecimal(values[3]);
            dailyValues.Close = Convert.ToDecimal(values[4]);
            dailyValues.Volume = Convert.ToDecimal(values[5]);
            dailyValues.AdjClose = Convert.ToDecimal(values[6]);
            return dailyValues;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

当然,您仍然可以添加默认构造函数,并且您将需要在解析失败时添加异常处理(您也可以使用TryParse它).

  • File.ReadAllLinesCSV文件中的所有行读取为字符串数组.
  • .Skip(1)跳过标题行.
  • .Select(v => DailyValues.FromCsv(v))使用LINQ to选择每一行,并创建一个新的DailyValues使用实例FromCsv方法.这会创建一个System.Collections.Generic.IEnumerable<CsvDemo.DailyValues>类型.
  • 最后,.ToList()转换IEnumerable为a List以匹配您想要的类型.

您可以简单地使用foreach循环将每个DailyValues实例添加到列表中,而不是使用Linq .

  • 虽然没有瑕疵,如果实际数据中有逗号,例如"洛杉矶,加利福尼亚"会分成2个单独的字段.如果您知道数据不包含字符串,那就OK. (6认同)
  • 这比stackoverflow上提供的任何其他解决方案简单得多:) (2认同)
  • 简单有效!+1 (2认同)