There is a code in which it is necessary that certain JSON(Date json:"d",Revenue json:"r", Gold json:"g") structures JSON(Date json:"d",Revenue json:"r", Gold json:"g") are counted and everything is output in CSV format CSV columns Date , Revenue , Gold . Here is an example of JSON text from which certain structures should be pulled out, everything is calculated in CSV and there is a lot of such data:

"logins": [["2011-11-06", 1]], "last_login": "Sun Nov 06 16:52:45 -0800 2011", "d": {"2010-11-05": { "gg": 0, "r": 4.99, "g": 0}, "2011-06-22": {"gg": 0, "1": {"g": 100, "r": 4.99 }, "g": 100, "r": 4.99}, "2011-07-16": {"gg": 0, "1": {"r": 9.99, "g": 200}, "r ": 9.99," g ": 200}," 2010-11-20 ": {" gg ": 0," r ": 4.99," g ": 100}}," h ": [{" d ": "2011-06-22", "wid": "1", "g": 100, "r": 4.99}, {"d": "2011-07-16", "r": 9.99, "g ": 200," wid ":" 1 "}]," t ": {" gg ": 0," 1 ": {" g ": 300," r ": 14.98}," r ": 24.96," g ": 400}}

And here is the code in which it is necessary to add, I started writing below and got stuck, there I understand that case should be used. I would be grateful for the help.

 package main import ( "database/sql" "log" _"github.com/go-sql-driver/mysql" "compress/zlib" "bytes" "encoding/json" "io/ioutil" "sort" "encoding/csv" "os" "strconv" "fmt" ) var ( data []byte dates []string ) type UserStatsData struct { Dates map[string]Info `json:"d"` } type Info struct { R json.Number `json:"r"` G int `json:"g"` D string `json:"-"` } func main() { db, err := sql.Open("mysql", "name:password@tcp(127.0.0.1:port)/database") if err != nil { panic(err.Error()) } defer db.Close() rows, err := db.Query(`SELECT data FROM user_stats ORDER BY created_at LIMIT 3`) if err != nil { log.Fatal(err) } defer rows.Close() file, err := os.Create("result.csv") if err != nil { fmt.Println(err) } defer file.Close() cont := 0 writer := csv.NewWriter(file) userStatsData := UserStatsData{} for rows.Next() { //userStatsData := UserStatsData{} err := rows.Scan(&data) if err != nil { log.Fatal(err) } if err := json.Unmarshal(data, &userStatsData); err != nil { r, err := zlib.NewReader(bytes.NewReader(data)) if err != nil { log.Panicf("\nCannot read archive %v", err); } r.Close() data, _ = ioutil.ReadAll(r) } if err := json.Unmarshal(data, &userStatsData); err != nil{ panic(err) } for userStats := range userStatsData.Dates { dates = append(dates, userStats) } sort.Strings(dates) var info []Info for _, date := range dates { i := userStatsData.Dates[date] iD = date info = append(info, i) } for _, i := range info { if cont == 0 { var record []string record = append(record, "Data") record = append(record, "Gold") record = append(record, "Revenue") writer.Write(record) cont++ } var record []string record = append(record, iD) record = append(record, strconv.Itoa(iG)) record = append(record, iRString()) writer.Write(record) cont++ } writer.Flush() err = writer.Error() if err != nil { panic(err) } } } 

    1 answer 1

    Decode the map, take the keys, sort, encode in CSV:

     type Data struct { Dates map[string]Info `json:"d"` } type Info struct { R json.Number `json:"r"` G int `json:"g"` D string `json:"-"` } d := Data{} err := json.Unmarshal(data, &d) if err != nil { panic(err) } var dates []string for k := range d.Dates { dates = append(dates, k) } sort.Strings(dates) var infos []Info for _, date := range dates { i := d.Dates[date] iD = date infos = append(infos, i) } enc := csv.NewWriter(os.Stdout) for _, i := range infos { err = enc.Write([]string{iD, strconv.Itoa(iG), iRString()}) if err != nil { panic(err) } } enc.Flush() err = enc.Error() if err != nil { panic(err) } 

    Playground: https://play.golang.org/p/bD9CzBSu7e .

    • Code changed at the beginning. - Sergio Hunter
    • @SergioHunter You are already asking a new question. And the new question is not clear to me, alas. - Ainar-G 4:39