json - 自定义 Json 编码(marshal)处理

标签 json go

我有一个第三方 json api 可以在 go 中使用。
它有一些端点以键值形式返回数据。
例如,这里是状态的 json:

{
  "result": {
    "0": "done",
    "1": "incomplete",
    "2": "completed",
    ....
  }
}

如您所见,它不是一个数组,而是一个对象。
是否可以将这种 json 编码为对象数组,例如

type Status struct {
    Id int
    Status string
}

不使用额外的结构,例如

type StatusReposne struct {
    Result map[string]string `json:"result"`
}

以及提取值的代码?

最佳答案

正如 @mkopriva 在评论中所说,如果没有一些额外的工作,这是不可能的。此代码确实提供了将数据编码/解码到 Status slice 中的方法:

func main() {
    sr := new(StatusReposne)

    json.Unmarshal([]byte(input), sr)
    fmt.Printf("%+v\n", sr)

    js, _ := json.Marshal(sr)
    fmt.Printf("%s\n", js)
}

type StatusReposne struct {
    Result []Status `json:"result"`
}

type Status struct {
    Id     int
    Status string
}

func (x *StatusReposne) MarshalJSON() ([]byte, error) {
    var buffer struct {
        Result map[string]string `json:"result"`
    }
    buffer.Result = make(map[string]string)
    for _, v := range x.Result {
        buffer.Result[strconv.Itoa(v.Id)] = v.Status
    }
    return json.Marshal(&buffer)
}

func (x *StatusReposne) UnmarshalJSON(b []byte) error {
    var buffer struct {
        Result map[string]string `json:"result"`
    }
    buffer.Result = make(map[string]string)
    json.Unmarshal(b, &buffer)
    for k, v := range buffer.Result {
        k, _ := strconv.Atoi(k)
        x.Result = append(x.Result, Status{Id: k, Status: v})
    }
    return nil
}

var input = `{
  "result": {
    "0": "done",
    "1": "incomplete",
    "2": "completed"
  }
}`

关于json - 自定义 Json 编码(marshal)处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43160569/

相关文章:

go - 如何用空模板覆盖模板 block ?

json - 如何使用 az --query 命令列出所有 json 字段但不列出它们的值?例如。 az 帐户列表 --query <某事>

javascript - Firebase 身份验证 Javascript : setCookie for pending Credential for redirect

python - 使用 pandas DataFrame 打开 JSON 文件

golang gocql.NewCluster 未定义没有字段或方法

go - 一个 Timer 有一个名为 C 的 chan 字段。要返回它,我必须在它后面加上括号吗?

mysql - 将 JSON 文件导入 MySQL 5.7

python - 尝试从 json 解析值时出现类型错误

go - 字符串列表 - golang

go - 使用 gopacket 更改目标端口