首页 > 解决方案 > Golang json根据键值对解组

问题描述

我有json如下

"data": [
    {
        "id": "recent_search",
        "items": [],
        "name": ""
    },
    {
        "id": "popular_search",
        "items": [],
        "name": ""
    },
    {
        "id": "digital",
        "items": [],
        "name": "DIGITAL"
    }
]

结构如下:

type universeTypeData struct {
Recent       universeSearchInfo 
Popular      universeSearchInfo 
Digital      universeSearchInfo 
}

type universeSearchInfo struct {
ID    string               `json:"id"`
Name  string               `json:"name"`
Items []universeSearchItem `json:"items"`
}

我想将我的json解组为“id”,其值为“recent_search”映射到最近,“id”值为“popular_search”映射到流行。有没有办法在golang中做到这一点?

我的做法是

for _, v := range result.Data {
    if v.ID == "in_category" {
        finalResult.Universe.InCategory.ID = v.ID
        finalResult.Universe.InCategory.Name = v.Name
        for _, abc := range v.Items {
            finalResult.Universe.InCategory.Items = append(finalResult.Universe.InCategory.Items, abc)
        }
    }
    if v.ID == "recent_search" {
        finalResult.Universe.Recent.ID = v.ID
        finalResult.Universe.Recent.Name = v.Name
        for _, abc := range v.Items {
            finalResult.Universe.Recent.Items = append(finalResult.Universe.Recent.Items, abc)
        }
    }
    if v.ID == "popular_search" {
        finalResult.Universe.Popular.ID = v.ID
        finalResult.Universe.Popular.Name = v.Name
        for _, abc := range v.Items {
            finalResult.Universe.Popular.Items = append(finalResult.Universe.Popular.Items, abc)
        }
    }

有没有更好的方法呢?

标签: jsongounmarshalling

解决方案


您想将 JSON 数组解压缩到不是自然映射的 Go 结构中。无论如何,您很可能应该首先在切片中解构,然后解析该切片。一些解决方法是使用 json.Decoder

dec := json.NewDecoder(JSONdataReader)
var res universeTypeData
// read open bracket
dec.Token()
// while the array contains values
for dec.More() {
    var m universeSearchInfo
    // decode an array value
    dec.Decode(&m)
    switch m.ID {
    case "recent_search":
        res.Recent = m
    case "popular_search":
        res.Popular = m
    case "digital":
        res.Digital = m
    }
}
// read closing bracket
dec.Token()

这使您可以一次进行即时解码,而无需消耗中间切片表示。工作示例


推荐阅读