golang unmarshal map [string] interface {}到包含带有meta数组的结构的结构

地鼠:

我有以下JSON数据通过API发送。我想将数据解组为下面定义的另一种结构方式。我怎样才能优雅地做到这一点?

{
    "_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
}
ramrunner:

这可能非常棘手,因为您有一个包含所有内容的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)
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

从String到map [string] interface {} golang

golang无法反映到map [interface {}] interface {}

YAML Unmarshal map [string] struct

带有map [string] string解组的Golang yaml.v2结构失败

在Golang中将属性添加到嵌套map [string] interface {}

在Golang中访问类型为map [string] interface {}的嵌套地图

有没有一种方法可以为golang唯一地使用map [string] interface {}?

是否可以将 map[string]string 转换为 map[string]interface{} 而无需在 golang 中使用 for 循环?

使用map [string] interface {}:

在map [string] interface {}的值上键入switch到[] map [string] interface {}

golang为类型为map [string] interface {}的对象设置新值

在golang中声明一个空的map [string] interface {}的内存成本/开销是多少?

如何从使用interface {}输入的golang map [string]字符串中提取值

在gRPC协议缓冲区golang中创建Map [string] interface {}类型的变量

在Golang中将两种或多种[] map [string] interface {}类型合并为一种

尝试xml时出错。解组结构类型为map [string] interface {}的结构

在golang json.Unmarshal中处理单个或数组结构的好方法是什么?

golang反映到[] interface {}

将map [interface {}] interface {}转换为map [string] string

map [string] interface {}和interface {}之间的区别

正确使用map [string] interface {}?

Golang Unmarshal XML属性

Golang Unmarshal JSON

正确初始化一个 map[string]interface 结构

使用map [string] int作为map [interface {}] interface {}类型的参数

golang中通过interface {}的结构的通用映射

在Golang中将interface {}转换为[] string

Unmarshal()返回空结构

包含结构的golang类型数组