Created
April 12, 2019 14:33
-
-
Save 200sc/3400b24fd232a436b990bd23ce81b880 to your computer and use it in GitHub Desktop.
Convert csvs with rows of fields to rows of objects
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"encoding/csv" | |
"fmt" | |
"os" | |
"strconv" | |
) | |
type Record struct { | |
key string | |
value string | |
} | |
func main() { | |
if len(os.Args) < 2 { | |
fmt.Println("Usage: go run convert.go example.csv") | |
return | |
} | |
input := os.Args[1] | |
f, err := os.Open(input) | |
if err != nil { | |
fmt.Println("Error opening input file", err) | |
return | |
} | |
r := csv.NewReader(f) | |
// Fields maps object ids to sets of defined key,value pairs | |
fields := make(map[int][]Record) | |
uniqueKeys := make(map[string]struct{}) | |
for record, err := r.Read(); err == nil; record, err = r.Read() { | |
if len(record) < 3 { | |
fmt.Println("Unexpected short record set", record) | |
return | |
} | |
id, err := strconv.Atoi(record[0]) | |
if err != nil { | |
fmt.Println("Expected integer ID for record", record) | |
return | |
} | |
fields[id] = append(fields[id], Record{record[1], record[2]}) | |
uniqueKeys[record[1]] = struct{}{} | |
} | |
i := 1 | |
keyIndices := make(map[string]int) | |
for k := range uniqueKeys { | |
keyIndices[k] = i | |
i++ | |
} | |
outFile, err := os.Create("converted" + input) | |
if err != nil { | |
fmt.Println("Error opening output file", err) | |
return | |
} | |
w := csv.NewWriter(outFile) | |
headers := make([]string, len(keyIndices)+1) | |
headers[0] = "id" | |
for k, i := range keyIndices { | |
headers[i] = k | |
} | |
w.Write(headers) | |
for id, records := range fields { | |
toWrite := make([]string, len(keyIndices)+1) | |
toWrite[0] = strconv.Itoa(id) | |
for _, record := range records { | |
toWrite[keyIndices[record.key]] = record.value | |
} | |
w.Write(toWrite) | |
} | |
w.Flush() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment