简体   繁体   English

Golang:将 json 对象解组为一个切片

[英]Golang: unmarshal json object into a slice

I have JSON like我有 JSON 之类的

{
  "a": {"key": "a", "value": 1,},
  "b": {"key": "b", "value": 1,},
}

Is there a way to unmarshal it into []*struct {Key string; Value int}有没有办法将它解组为[]*struct {Key string; Value int} []*struct {Key string; Value int} , preserving the order of the structures? []*struct {Key string; Value int} ,保留结构的顺序?

If I unmarshal the JSON into map[string]*struct {Key string; Value int}如果我将 JSON 解组为map[string]*struct {Key string; Value int} map[string]*struct {Key string; Value int} and then convert the map into a slice, I'll lose the order of the structures. map[string]*struct {Key string; Value int}然后将地图转换为切片,我将失去结构的顺序。

To preserve order, use Decoder.Token and Decoder.More to walk through the top-level JSON object.要保留顺序,请使用Decoder.TokenDecoder.More遍历顶级 JSON 对象。

r := strings.NewReader(`
 {
   "a": {"key": "a", "value": 1},
   "b": {"key": "b", "value": 1}
 }`)

d := json.NewDecoder(r)
t, err := d.Token()
if err != nil || t != json.Delim('{') {
    log.Fatal("expected object")
}
var result []*element
for d.More() {
    k, err := d.Token()
    if err != nil {
        log.Fatal(err)
    }
    var v element
    if err := d.Decode(&v); err != nil {
        log.Fatal(err)
    }
    result = append(result, &v)
    fmt.Println("key:", k, "value:", v)
}

Run it on the Go Playground在 Go Playground 上运行它

Change the calls to log.Fatal to the error handling appropriate for your application.将对 log.Fatal 的调用更改为适合您的应用程序的错误处理。

This answer edits the JSON in the question to make the JSON valid.此答案编辑问题中的 JSON 以使 JSON 有效。

The field names in the struct element type must be exported .必须导出结构元素类型中的字段名称。

The easiest way that I found was to use jsonparser.ObjectEach :我发现的最简单的方法是使用jsonparser.ObjectEach

import "github.com/buger/jsonparser"

...

var ss []*struct{Key string; Value int}
err = jsonparser.ObjectEach(data, func(key []byte, value []byte, dataType jsonparser.ValueType, offset int) error {
    var s struct{Key string; Value int}
    if err := json.Unmarshal(value, &s); err != nil {
        return err
    }
    *ss = append(*ss, &s)
    return nil
})

You could use the map[string]interface{} to unmarshal the json string.您可以使用 map[string]interface{} 解组 json 字符串。 The code is this代码是这样的

func test() {
    jsonStr := `
 {
   "a": {"key": "a", "value": 1},
   "b": {"key": "b", "value": 1}
 }`
    var mapResult map[string]interface{}
    err := json.Unmarshal([]byte(jsonStr), &mapResult)
    if err != nil {
        fmt.Println("JsonToMapDemo err: ", err)
    }
    fmt.Println(mapResult)
}

the output is: map[a:map[key:a value:1] b:map[key:b value:1]]输出为:map[a:map[key:a value:1] b:map[key:b value:1]]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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