Skip to content

Instantly share code, notes, and snippets.

@jmhungdev
Last active March 16, 2023 04:02
Show Gist options
  • Save jmhungdev/a210fdabbfb0c43ea320f3bc8ed41d56 to your computer and use it in GitHub Desktop.
Save jmhungdev/a210fdabbfb0c43ea320f3bc8ed41d56 to your computer and use it in GitHub Desktop.
Manipulating struct into csv in Golang
// stackoverflow post:
// https://stackoverflow.com/questions/75739563/converting-struct-to-csv-string/75740486#75740486
// [][]string or []Struct{} are preferred types to represent table data (csv) because of golang package ecosystem
// The case below is a special Data struct type that doesn't fit either
// which requires an additional step to transform it into [][]string before "encoding/csv" package can transform it into csv
package main
import (
"encoding/csv"
"log"
"os"
"strconv"
)
type Data struct {
id []string
col1 []float64
col2 []float64
}
func TransformDataTo2DSlice(d Data) [][]string {
numRows := len(d.id)
result := make([][]string, numRows+1)
// Add header row
result[0] = []string{"id", "col1", "col2"}
// Add data rows
for i := 0; i < numRows; i++ {
result[i+1] = []string{d.id[i],
strconv.FormatFloat(d.col1[i], 'f', -1, 64),
strconv.FormatFloat(d.col2[i], 'f', -1, 64),
}
}
return result
}
func main() {
d := Data{
id: []string{"id_1", "id_1", "id_1", "id_1"},
col1: []float64{340.384926, 321.385028, 520.341473, 500.385473},
col2: []float64{123.285031, 4087.284675, -8958.284216, -7612.283668},
}
d2dslice := TransformDataTo2DSlice(d)
// fmt.Printf("%+v", d2dslice)
// [[id, col1, col2],
// [id_1, 340.384926, 123.285031],
// [id_1, 321.385028, 4087.284675],
// [id_1, 520.341473, -8958.284216],
// [id_1,500.385473,-7612.283668]]
w := csv.NewWriter(os.Stdout)
w.WriteAll(d2dslice)
if err := w.Error(); err != nil {
log.Fatalln("error writing csv:", err)
}
// stdout:
// id,col1,col2
// id_1,340.384926,123.285031
// id_1,321.385028,4087.284675
// id_1,520.341473,-8958.284216
// id_1,500.385473,-7612.283668
}
@jmhungdev
Copy link
Author

To write csv into a string type variable instead:

   buf := new(bytes.Buffer)
    w := csv.NewWriter(buf)
    w.WriteAll(d2dslice)

    if err := w.Error(); err != nil {
        log.Fatalln("error writing csv:", err)
    }

    csvString := buf.String()

    fmt.Printf("%T\n", csvString)  // print the variable type
    // string

    fmt.Printf("%+v\n", csvString) // print the variable value
    // id,col1,col2
    // id_1,340.384926,123.285031
    // id_1,321.385028,4087.284675
    // id_1,520.341473,-8958.284216
    // id_1,500.385473,-7612.283668

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment