如果 GO 中的外部元素不相同,如何将嵌套的 json 解组为结构

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

你好,我想知道是否可以将给定的 json 解组为结构

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

这是 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"
    }
]
}

如您所见,名称字段可以采用任何名称,因为它是电影的标题。有没有一种有效的方法可以将它放入上面的结构中? 任何帮助都会很好,谢谢

考虑到它的动态特性,使用地图[string]界面可能更容易,因为您将无法定义像 asd123 和 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))

}

上面的方法可能是更好的方法,但我提供了一个简单的示例。最好的方法是更好地组织 json 数据,以便它更好地适合结构,否则使用反射。无需更多工作,我会使用上面的 for 循环,并将其添加到对我有意义的结构中,以便它可以更轻松地访问数据。考虑上面 JSON 解析器的开始,所以现在您可以访问 json 数据,将其装入结构,然后更改周围的数据。