Home > Software engineering >  mapstructure json into a structure with nested dictionary
mapstructure json into a structure with nested dictionary

Time:01-12

I am new to golang. I have a json file with nested structures that I want to parse and populate.

I am trying to use mapstructure to try and populate. I am able to do it for simple structures. But when it comes to array for dictionaries(key:struct). The map[string]interface{} seems to fail with runtime error: index out of range.

I tried to do the following for the json example below.

type Window struct {
    loc    []int
    wrtc   string
    label  string
}

type View struct {
    windows   []Window
}

type Views struct {
    views []View
}

type Desktop struct {
    views                 []Views  `mapstructure:views`
    rotation_speed        string   `mapstructure:"rotationSpeed" json:rotationSpeed"`
}

func main() {
        file, _ := ioutil.ReadFile("test.json")

        data := Desktop{}

        _ = json.Unmarshal([]byte(file), &data)

        fmt.Println("data: ", data.views[0])
}

{
"desktop": {
    "view": [{// configs for view1
                 "random_id1": {
                         "loc": [0,0,640,360],
                         "wrtc": "some string",
                         "label": "window 1"
                 },
                 "random_id213443": {
                         "loc": [640,360,1280,720],
                         "wrtc": "some string blah",
                         "label": "window 2"
                 },
                 // more windows with random ids....
              },
              {
               // configs for view2...
              }
             ],
    "rotationSpeed": 30
}

Since the window id is random I am not able to define it in a struct. I tried using mapstructure:",squash" but that seems to fail as well.

I appreciate any help with this.

CodePudding user response:

@Burak Serdar is right

You don't need mapstructure. JSON unmarshaling can deal with this.

you code have many error, like struct, uppercase, 'views' etc..

follow is a demo:

package main

import (
    "encoding/json"
    "fmt"
)

var data = `
{
    "desktop":{
        "view":[
            {
                "random_id1_1":{
                    "loc":[
                        0,
                        0,
                        640,
                        360
                    ],
                    "wrtc":"some string",
                    "label":"window 1"
                },
                "random_id1_2":{
                    "loc":[
                        640,
                        360,
                        1280,
                        720
                    ],
                    "wrtc":"some string blah",
                    "label":"window 2"
                }
            },
            {
                "random_id2_1":{
                    "loc":[
                        0,
                        0,
                        640,
                        360
                    ],
                    "wrtc":"some string",
                    "label":"window 1"
                },
                "random_id2_2":{
                    "loc":[
                        640,
                        360,
                        1280,
                        720
                    ],
                    "wrtc":"some string blah",
                    "label":"window 2"
                }
            }
        ],
        "rotationSpeed":30
    }
}
`

type Window struct {
    Loc   []int
    Wrtc  string
    Label string
}

type Desktop struct {
    View           []map[string]Window
    Rotation_speed int `json:"rotationSpeed" mapstructure:"rotationSpeed"`
}

type Config struct {
    Desktop Desktop
}

func main() {
    c := Config{}
    json.Unmarshal([]byte(data), &c)
    fmt.Println("json.Unmarshal: ", c)
}
json.Unmarshal:  {{[map[random_id1_1:{[0 0 640 360] some string window 1} random_id1_2:{[640 360 1280 720] some s
tring blah window 2}] map[random_id2_1:{[0 0 640 360] some string window 1} random_id2_2:{[640 360 1280 720] some
 string blah window 2}]] 30}}

also you can use mapstructure by "remain", if you want View struct

type Window struct {
    Loc   []int
    Wrtc  string
    Label string
}

type View struct {
    Windows map[string]Window `mapstructure:",remain"`
}

type Desktop struct {
    View           []View
    Rotation_speed int `json:"rotationSpeed" mapstructure:"rotationSpeed"`
}

type Config struct {
    Desktop Desktop
}

func main() {
    c2 := Config{}
    m := map[string]interface{}{}
    _ = json.Unmarshal([]byte(data), &m)
    mapstructure.Decode(m, &c2)
    fmt.Println("mapstructure: ", c2)
}
  •  Tags:  
  • go
  • Related