John Smith John Smith - 4 months ago 9
JSON Question

Parse nested JSON into struct?

I want to parse the following JSON output:

{
"total":5689,
"result":{
"6581":{
"percent":37.79,
"count":2150
},
"6591":{
"percent":35.31,
"count":2009
},
"6601":{
"percent":26.89,
"count":1530
}
}
}


I have read that JSON can be parsed into a struct if the format is known:

package main

import (
"encoding/json"
"fmt"
"os"
)

type VoteResult struct {
Total int `json:"total"`
Result struct {
Efid1 struct {
Percent float64 `json:"percent"`
Count int `json:"count"`
}
Efid2 struct {
Percent float64 `json:"percent"`
Count int `json:"count"`
}
Efid3 struct {
Percent float64 `json:"percent"`
Count int `json:"count"`
}
}
}

func main() {
b := []byte(`{"total":5689,"result":{"6581":{"percent":37.79,"count":2150}
,"6591":{"percent":35.31,"count":2009},"6601":{"percent":26.89,"count":1530}}}`)

var v VoteResult

err := json.Unmarshal(b, &v)
if err != nil {
fmt.Fprintf(os.Stderr, "%v\n", err)
os.Exit(1)
}

fmt.Println(v)
}


Go Playground

This is the output, but something is wrong as the nested structs are not filled with data:

{5689 {{0 0} {0 0} {0 0}}}


What am I doing wrong?

Answer

The result part of the JSON is a dictionary mapping strings to objects. Try this instead (https://play.golang.org/p/BCNHw-OH2I):

type VoteResult struct {
    Total  int `json:"total"`
    Result map[string]struct {
        Percent float64 `json:"percent"`
        Count   int     `json:"count"`
    }
}

EDIT

As an alternative, if those strings are truly fixed, you could do this:

type VoteResult struct {
    Total  int `json:"total"`
    Result struct {
        Efid1 struct {
            Percent float64 `json:"percent"`
            Count   int     `json:"count"`
        } `json:"6581"`
        Efid2 struct {
            Percent float64 `json:"percent"`
            Count   int     `json:"count"`
        } `json:"6591"`
        Efid3 struct {
            Percent float64 `json:"percent"`
            Count   int     `json:"count"`
        } `json:"6601"`
    }
}

Here we've just decided that Efid1 has the JSON key 6591, etc. But I suspect a map of strings to structs is a better fit for the data structure you have.