简体   繁体   中英

How to unmarshal nested json to a struct, if the outer element is not the same in GO

Hi i wonder if it is possible to unmarshal this given json to a struct

type Movie struct {
    Title string
    Actors []string
    ID int
    Length int
    RelaseDate string
}

Here is an example of the json

{
"movies": [
    {
        "movie_title_A": {
            "actors": [
                "<actorID1123123>",
                "<actorID1123123>",
                "<actorID1123123>",
                "<actorID1123123>",
                "<actorID1123123>",
                "<actorID1123123>...."
            ]
        },
        "ID": 99992,
        "length": 120,
        "relaseDate": "2.10.2012"
    },
    {
        "movie_title_B": {
            "actors": [
                "<actorID1123123>",
                "<actorID1123123>",
                "<actorID1123123>",
                "<actorID1123123>",
                "<actorID1123123>",
                "<actorID1123123>...."
            ]
        },
        "ID": 123124,
        "length": 90,
        "relaseDate": "10.10.2012"
    }
]
}

As you can see the Name field can take on any name, since it is the title of the movie. Is there an efficient way to put it into the struct above? Any help would be nice, thanks

given it's dynamic nature it might be easier use a map[string]interface as you'll not be able to define dynamic keys like asd123 and 2movie23123.

package main

import (
    "encoding/json"
    "fmt"
)

const j = `{
    "movies": [
        {
            "asd123": {
                "actors": [
                    "<actorID1123123>",
                    "<actorID1123123>",
                    "<actorID1123123>",
                    "<actorID1123123>",
                    "<actorID1123123>",
                    "<actorID1123123>"
                ]
            },
            "ID": 99992,
            "length": 120,
            "relaseDate": "2.10.2012"
        },
        {
            "2movie23123": {
                "actors": [
                    "<actorID1123123>",
                    "<actorID1123123>",
                    "<actorID1123123>",
                    "<actorID1123123>",
                    "<actorID1123123>",
                    "<actorID1123123>"
                ]
            },
            "ID": 123124,
            "length": 90,
            "relaseDate": "10.10.2012"
        }
    ]
    }`

// Movies ...
type Movies struct {
    Name        string
    ID          float64
    Length      float64
    ReleaseDate string
    Actors      []interface{}
}

func main() {
    data := map[string]interface{}{}
    err := json.Unmarshal([]byte(j), &data)
    if err != nil {
        panic(err)
    }
    // printing it out to show you it marshaled
    // b, _ := json.MarshalIndent(data, "", " ")
    // fmt.Println(string(b))
    //
    var myMovies []Movies

    for _, d := range data {
        temp := Movies{}
        converting := d.([]interface{})
        for _, movie := range converting {
            convertingMovie := movie.(map[string]interface{})
            temp.Length = convertingMovie["length"].(float64)
            temp.ID = convertingMovie["ID"].(float64)
            temp.ReleaseDate = convertingMovie["relaseDate"].(string)
            // getting rid of these keys so the for loop below doesn't iterate on them
            // need the for loop cuz I don't know what the key name is
            delete(convertingMovie, "length")
            delete(convertingMovie, "ID")
            delete(convertingMovie, "relaseDate")
            for key, val := range convertingMovie {
                temp.Name = key
                actors := val.(map[string]interface{})
                temp.Actors = actors["actors"].([]interface{})
            }
        }
        myMovies = append(myMovies, temp)
    }

    b, _ := json.MarshalIndent(myMovies, "", " ")
    fmt.Println(string(b))

}

Probably a better way to do it above, but I provided a quick example. The best way would be to organize the json data better so that it fits into a struct better, otherwise the use reflection. Without to much more work, I'd use the for loop above, and add it to a struct in a may that makes sense to me and so that it can access the data easier. Consider above the start of the JSON parser, so now that you can access the json data, fit it into a struct then, change data around.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM