go - golang unmarshal map[string]interface{} 到一个包含带有 meta 的数组的结构
问题描述
我有以下通过 API 传来的 json 数据。我想将这些数据解组为不同的结构方式,如下所述。我怎样才能以优雅的方式做到这一点?
{
"_meta": {
"count": 2,
"total": 2
},
"0": {
"key": "key0",
"name": "name0"
},
"1": {
"key": "key1",
"name": "name1"
},
"2": {
"key": "key2",
"name": "name2"
}
// It goes on..
}
type Data struct {
Meta Meta `json:"_meta,omitempty"`
Elements []Element
}
type Element struct {
Key string
Name string
}
type Meta struct{
Count int
Total int
}
解决方案
这可能非常棘手,因为您有一个包含所有内容的 json 对象。所以我采用了解组将字符串映射到 *json.RawMessage 的方法,然后从那里修复结构。
为此,您将使用自定义 Unmarshaler,它的好处是您可以延迟内部消息的实际解析,直到您需要它们。
因此,例如,如果您的元字段错误或它所说的数字与 map-1 的长度不匹配,您可能会过早退出。
package main
import (
"encoding/json"
"fmt"
)
type jdata map[string]*json.RawMessage
type data struct {
Meta Meta
Elements []Element
}
//Element is a key val assoc
type Element struct {
Key string
Name string
}
//Meta holds counts and total of elems
type Meta struct {
Count int
Total int
}
var datain = []byte(`
{
"_meta": {
"count": 2,
"total": 2
},
"0": {
"key": "key0",
"name": "name0"
},
"1": {
"key": "key1",
"name": "name1"
},
"2": {
"key": "key2",
"name": "name2"
}
}`)
func (d *data) UnmarshalJSON(buf []byte) (err error) {
var (
meta *json.RawMessage
ok bool
)
jdata := new(jdata)
if err = json.Unmarshal(buf, jdata); err != nil {
return
}
if meta, ok = (*jdata)["_meta"]; !ok {
return fmt.Errorf("_meta field not found in JSON")
}
if err = json.Unmarshal(*meta, &d.Meta); err != nil {
return
}
for k, v := range *jdata {
if k == "_meta" {
continue
}
elem := &Element{}
if err = json.Unmarshal(*v, elem); err != nil {
return err
}
d.Elements = append(d.Elements, *elem)
}
return nil
}
func main() {
data := &data{}
if err := data.UnmarshalJSON(datain); err != nil {
panic(err)
}
fmt.Printf("decoded:%v\n", data)
}
推荐阅读
- javascript - 使用相同的 url 刷新 this.props.history.push 上的页面
- c - 编辑结构数组的成员时遇到问题
- visual-studio-code - 为什么 VS Code 会抛出此错误(ARDUINO)?
- java - 使用 java 和 Selenium 通过代理丰富标头
- laravel - Laravel 注销路由无法正常工作
- javascript - 从本地机器上传文件时 Quill 未定义
- javascript - 如何在 graalvm 上使用 yarn 运行 node.js 项目?
- php - Laravel - SQLSTATE [HY000] [1049] 未知数据库
- r - 是否有任何修改/另一个函数可以针对一个字符串变量绘制两个数值变量?
- c++ - 每次我进行继承时都需要 boost::serialization::base_object 吗?