使用嵌套数组进行JSON编组?

huangapple go评论75阅读模式
英文:

Marshaling JSON with nested array?

问题

我想创建以下格式的JSON:

{
  "name": "val1",
  "version": "val2",
  "type": "val3",
  "settings": [
    "setting1",
    "setting2",
    "setting3",
    [
      "option1",
      "option2"
    ] 
  ]
}

但我不知道如何在settings内创建嵌套数组:

package main

import (
        "encoding/json"
        "fmt"
)

type Config struct {
        Name     string   `json:"name"`
        Version  string   `json:"version"`
        Type     string   `json:"type"`
        Settings []string `json:"settings"`
}

func main() {
        settings := []string{"setting1", "setting2", "setting3"}
        options := []string{"option1", "option2"}
        setopts := append(settings, options...)

        c := &Config{"val1", "val2", "val3", setopts}

        j, err := json.Marshal(c)
        if err != nil {
                panic(err)
        }

        fmt.Println(string(j))
}

通过jq输出以提高可读性:

$ ./main | jq
{
  "name": "val1",
  "version": "val2",
  "type": "val3",
  "settings": [
    "setting1",
    "setting2",
    "setting3",
    "option1",
    "option2"
  ]
}

结果是option1option2settings数组内的值,但它们应该是settings的嵌套数组内的值。而且,在编组时,选项可能不总是存在,在这些情况下,不应创建嵌套数组。

我该如何实现这个目标?

英文:

I want to create JSON like this:

{
  "name": "val1",
  "version": "val2",
  "type": "val3",
  "settings": [
    "setting1,
    "setting2",
    "setting3",
    [
      "option1",
      "option2"
    ] 
  ]
}

But I don't know how to create the nested array inside settings:

package main

import (
        "encoding/json"
        "fmt"
)

type Config struct {
        Name     string   `json:"name"`
        Version  string   `json:"version"`
        Type     string   `json:"type"`
        Settings []string `json:"settings"`
}

func main() {
        settings := []string{"setting1", "setting2", "setting3"}
        options := []string{"option1", "option2"}
        setopts := append(settings, options...)

        c := &Config{"val1", "val2", "val3", setopts}

        j, err := json.Marshal(c)
        if err != nil {
                panic(err)
        }

        fmt.Println(string(j))
}

Output piped through jq for readability:

$ ./main | jq
{
  "name": "val1",
  "version": "val2",
  "type": "val3",
  "settings": [
    "setting1",
    "setting2",
    "setting3",
    "option1",
    "option2"
  ]
}

The result is that option1 and option2 is values inside settings array, but they should be inside a nested array of settings instead. Also, the options may not always be present when marshaling and in those cases the nested array should not be created.

How can I accomplish this?

答案1

得分: 4

你在这里展示的输出可以被描述为 JSON 字符串或字符串数组。

你可以使用 []interface{} 来建模它,并向其附加字符串或切片:

type Config struct {
        Name     string        `json:"name"`
        Version  string        `json:"version"`
        Type     string        `json:"type"`
        Settings []interface{} `json:"settings"`
}

func main() {
        settings := []interface{}{
              "setting1", 
              "setting2", 
              "setting3",
              []string{"option1", "option2"},
        }

        c := &Config{"val1", "val2", "val3", settings}

        j, err := json.Marshal(c)
        if err != nil {
                panic(err)
        }

        fmt.Println(string(j))
}

Playground: https://go.dev/play/p/8LPAVBPmd8w

英文:

The output that you show here:

    "setting1",
    "setting2",
    "setting3",
    [
      "option1",
      "option2"
    ]

can be described as JSON string or array-of-strings.

You may model this with []interface{}, and append to it either strings or slices:

type Config struct {
        Name     string        `json:"name"`
        Version  string        `json:"version"`
        Type     string        `json:"type"`
        Settings []interface{} `json:"settings"`
}

func main() {
        settings := []interface{}{
              "setting1", 
              "setting2", 
              "setting3",
              []string{"option1", "option2"},
        }

        c := &Config{"val1", "val2", "val3", settings}

        j, err := json.Marshal(c)
        if err != nil {
                panic(err)
        }

        fmt.Println(string(j))
}

Playground: https://go.dev/play/p/8LPAVBPmd8w

huangapple
  • 本文由 发表于 2021年12月13日 04:35:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/70327490.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定