package records import ( "encoding/csv" "io" "log" "strconv" ) type FinancialData struct { Date string Open, High, Low, Close, Adj_Close, Volume float64 } func readCsvLine(cols []string, line []string) *FinancialData { data := new(FinancialData) for i, col := range line { switch cols[i] { case "Date": data.Date = col case "Open": data.Open = toFloat(col) case "High": data.High = toFloat(col) case "Low": data.Low = toFloat(col) case "Close": data.Close = toFloat(col) case "Adj Close": data.Adj_Close = toFloat(col) case "Volume": data.Volume = toFloat(col) } } return data } func toFloat(v string) float64 { f, err := strconv.ParseFloat(v, 64) if err != nil { log.Fatalln(err) } return f } func readCsvHeader(line []string) []string { cols := []string{} for _, col := range line { cols = append(cols, col) } return cols } func ReadCsv(in io.Reader) ([]string, []FinancialData) { cols := []string{} data := []FinancialData{} csvReader := csv.NewReader(in) for { line, err := csvReader.Read() if err == io.EOF { break } else if err != nil { log.Fatal(err) } if len(cols) == 0 { cols = readCsvHeader(line) } else { data = append(data, *readCsvLine(cols, line)) } } return cols, data }