为了账号安全,请及时绑定邮箱和手机立即绑定

在 Go 中的嵌入式结构中组合任意 JSON 对象

在 Go 中的嵌入式结构中组合任意 JSON 对象

Go
蛊毒传说 2021-09-27 16:05:46
我正在尝试以{{"s":"v1", "t":"v2"}, {"s":"v3", "t":"v4"}, etc}Go 中的嵌入式结构的形式生成 JSON 对象。当提前知道所有Problem项目时,一切都很好type Problems []Problem,如ONE()下面的func和Playground demo此处所示。但是,如果某些 K:V 对包含空值,我想避免获取{{a},{},{c}}而不是所需的{{a},{c}},如TWO()下面的func和演示中所示。或者,我如何probs := Problems{prob0, prob1, prob2, etc}在不提前知道是否会添加或省略问题项目的情况下随意组合?package mainimport (    "encoding/json"    "fmt")type Problem struct {     S string `json:"s,omitempty"`     T string `json:"t,omitempty"`} type Problems []Problem func main() {     ONE()     TWO()} func ONE() {     prob0 := Problem{S: "s0", T: "t0"}     prob1 := Problem{S: "s1", T: "t1"}     prob2 := Problem{S: "s2", T: "t2"}     probs := Problems{prob0, prob1, probe}       // fmt.Println(probs) // CORRECT: [{s0 t0} {s1 t1} {s2 t2}]     b, _ := json.Marshal(probs)     fmt.Println(string(b))       // CORRECT: [{"s":"s0","t":"t0"},{"s":"s1","t":"t1"},{"s":"s2","t":"t2"}]``} func TWO() {     prob0 := Problem{S: "s0", T: "t0"}     prob1 := Problem{S: "", T: ""} // empty values omited BUT NOT {}     prob2 := Problem{S: "s2", T: "t2"}     probs := Problems{prob0, prob1, probe}       // fmt.Println(probs)       // GOT:    [{s0 t0} { } {s2 t2}]       // WANTED: [{s0 t0} {s2 t2}]     b, _ := json.Marshal(probs)     fmt.Println(string(b))       // GOT:    [{"s":"s0","t":"t0"},{},{"s":"s2","t":"t2"}]       // WANTED: [{"s":"s0","t":"t0"},{"s":"s2","t":"t2"}]}
查看完整描述

3 回答

?
HUX布斯

TA贡献1876条经验 获得超6个赞

一旦您将一个元素添加到您编组的数组/切片中,您就无能为力了。如果元素在数组/切片中,它将被编组(将包含在 JSON 输出中)。该json.Marshal()函数如何猜测您不想编组的元素?它不能。


您必须排除不会出现在输出中的元素。在您的情况下,您要排除空Problem结构。


最好/最简单的是创建一个辅助函数,[]Problem为您创建切片,排除空结构:


func createProbs(ps ...Problem) []Problem {

    // Remove empty Problem structs:

    empty := Problem{}

    for i := len(ps) - 1; i >= 0; i-- {

        if ps[i] == empty {

            ps = append(ps[:i], ps[i+1:]...)

        }

    }

    return ps

}

使用它创建一个切片是这样的:


probs := createProbs(prob0, prob1, prob2)

在Go Playground上尝试修改后的应用程序。


修改后的代码的输出(注意缺少空结构):


[{"s":"s0","t":"t0"},{"s":"s1","t":"t1"},{"s":"s2","t":"t2"}]

[{"s":"s0","t":"t0"},{"s":"s2","t":"t2"}]


查看完整回答
反对 回复 2021-09-27
?
慕仙森

TA贡献1827条经验 获得超7个赞

你不能轻易做到这一点。空结构也是一个结构,它将被序列化为{}. 甚至nil值将被序列化为null.


以下代码:包主


import (

    "encoding/json"

    "fmt"

)


func main() {

     xs := []interface{}{struct{}{},nil}

     b, _ := json.Marshal(xs)

     fmt.Println(string(b))

}

将产生:


[{},null]

Playground


解决方案是为类型实现json.Marshaller接口Problems以跳过空结构。


查看完整回答
反对 回复 2021-09-27
  • 3 回答
  • 0 关注
  • 254 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信