I have a CSV file with a listing of varied data(datetime, decimal). Sample line from 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
I have a list of objects created that I want to read each of the lines into. The constructor for the objects is below, each of the fields from each CSV line is used and assigned here.
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>();
Is there an easy way to read each line of the CSV into my list values
and appropriately assign each attribute (i.e. date, open, high)?
Why not just parse these explicitly? You have a limited number of properties, so it's not very difficult. Instead of using a constructor requiring many arguments, I used a static method that returns a new DailyValues
instance as it's return type. This is similar to DateTime.FromBinary
etc.
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; } } }
Of course, you can still add a default constructor, and you will want to add exception handling in case the parsing fails (you can also use TryParse
for that).
File.ReadAllLines
reads all lines from the CSV file into a string array..Skip(1)
skips the header line..Select(v => DailyValues.FromCsv(v))
uses Linq to select each line and create a new DailyValues
instance using the FromCsv
method. This creates a System.Collections.Generic.IEnumerable<CsvDemo.DailyValues>
type..ToList()
convers the IEnumerable
to a List
to match the type you want.Instead of using Linq you could have simply used a foreach
loop to add each DailyValues
instance to your list.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With