package main import "encoding/csv" import "encoding/json" import "io" import "log" import "os" import "strconv" type StateData struct { Id int Name string Abbreviation string Country string Type_state string Sort int Status string Occupied string Notes string Fips_state string Assoc_press string Standard_federal_region string Census_region int Census_region_name string Census_division int Census_division_name string Circuit_court int } func readCsvHeader(line []string) (map[string]int, error) { columns := make(map[string]int) for i, col := range line { columns[col] = i } return columns, nil } func readCsvLine(line []string, columns map[string]int) (*StateData, error) { var err error data := new(StateData) for i, col := range line { switch i { case columns["id"]: data.Id, err = strconv.Atoi(col) if err != nil { return data, err } case columns["name"]: data.Name = col case columns["abbreviation"]: data.Abbreviation = col case columns["country"]: data.Country = col case columns["type"]: data.Type_state = col case columns["sort"]: data.Sort, err = strconv.Atoi(col) if err != nil { return data, err } case columns["status"]: data.Status = col case columns["occupied"]: data.Occupied = col case columns["notes"]: data.Notes = col case columns["fips_state"]: data.Fips_state = col case columns["assoc_press"]: data.Assoc_press = col case columns["standard_federal_region"]: data.Standard_federal_region = col case columns["census_region"]: data.Census_region, err = strconv.Atoi(col) if err != nil { return data, err } case columns["census_region_name"]: data.Census_region_name = col case columns["census_division"]: data.Census_division, err = strconv.Atoi(col) if err != nil { return data, err } case columns["census_division_name"]: data.Census_division_name = col case columns["circuit_court"]: data.Circuit_court, err = strconv.Atoi(col) if err != nil { return data, err } } } return data, nil } func readCsv(in io.Reader) map[string]*StateData { data := make(map[string]*StateData) csvReader := csv.NewReader(in) var header map[string]int for { line, err := csvReader.Read() if err == io.EOF { break } else if err != nil { log.Fatal(err) } if len(header) == 0 { header, err = readCsvHeader(line) if err != nil { log.Fatal(err) } } else { d, err := readCsvLine(line, header) if err != nil { log.Println("Invalid line", err) // skip } else { data[d.Abbreviation] = d } } } return data } func main() { if len(os.Args) < 2 { log.Fatalln("Usage statecsv ") } // read input csv, err := os.Open(os.Args[1]) if err != nil { log.Fatalln("Error reading file", err) } defer csv.Close() // parse data data := readCsv(csv) // convert JSON var writer io.Writer if len(os.Args) > 2 { f, ferr := os.Create(os.Args[2]) if ferr != nil { panic(ferr) } defer f.Close() writer = f } else { writer = os.Stdout } err = json.NewEncoder(writer).Encode(data) if err != nil { panic(err) } }