Depending on how you count, this is my first Go program. I'm trying to read a CSV into a two-dimensional array of some numeric type, and then print it out.
(I want to use this to read "edge weights" to build a Graph; that is my next mission, unrelated to the code below.)
So the code below works. But particularly as I'm new to the language, I'd like to know:
- Are there shorter ways to accomplish the same functionality?
- Any ways to make this code more idiomatic?
- float64 feels arbitrary, but Go is statically typed -- any way I can make this more dynamic, allowing other types?
Here 'tis; rip her apart if you want! Trying to learn.
package csfloat
import (
"encoding/csv"
"fmt"
"os"
"strconv"
"strings"
)
// make2dFloatArray makes a new 2d array of float64s based on the
// rowCount and colCount provided as arguments
func make2dFloatArray(rowCount int, colCount int) [][]float64 {
values := make([][]float64, rowCount)
for rowIndex := range values {
values[rowIndex] = make([]float64, colCount)
}
return values
}
// stringValuesToFloats converts a 2d array of strings into a 2d array
// of float64s.
func stringValuesToFloats(stringValues [][]string) ([][]float64, error) {
values := make2dFloatArray(len(stringValues), len(stringValues[0]))
for rowIndex, _ := range values {
for colIndex, _ := range values[rowIndex] {
var err error = nil
trimString :=
strings.TrimSpace(stringValues[rowIndex][colIndex])
values[rowIndex][colIndex], err =
strconv.ParseFloat(trimString, 64)
if err != nil {
fmt.Println(err)
return values, err
}
}
}
return values, nil
}
// ReadFromCsv will read the csv file at filePath and return its
// contents as a 2d array of floats
func ReadFromCsv(filePath string) ([][]float64, error) {
file, err := os.Open(filePath)
if err != nil {
return nil, err
}
reader := csv.NewReader(file)
stringValues, err := reader.ReadAll()
if err != nil {
return nil, err
}
values, err := stringValuesToFloats(stringValues)
if err != nil {
return nil, err
}
return values, nil
}