2 回答
TA贡献1865条经验 获得超7个赞
一般来说,对于这种情况,您必须json.Unmarshal使用interface{}.
b := []byte(`{ "key1": { "key2": { "key3": "Found data" } } } `)
var f interface{}
if err := json.Unmarshal(b, &f); err != nil {
panic(err)
}
fmt.Println(f)
现在您可以使用一堆类型断言来探索f,例如查找它包含哪些键:
m := f.(map[string]interface{})
for k, v := range m {
if k == "key3" {
fmt.Println("found key3. maps to", v)
}
}
如果您在此级别找不到 key3,请使用递归检查所有值 -它们是否与 key3 键映射,等等......类似
func findNested(m map[string]interface{}, s string) (bool, interface{}) {
// Try to find key s at this level
for k, v := range m {
if k == s {
return true, v
}
}
// Not found on this level, so try to find it nested
for _, v := range m {
nm := v.(map[string]interface{})
found, val := findNested(nm, s)
if found {
return found, val
}
}
// Not found recursively
return false, nil
}
注意:此功能很快被破解在一起,可能会错误处理一堆极端情况。它在这里展示了关键思想 - 将其用作满足您特定需求的基础
TA贡献1811条经验 获得超5个赞
我个人喜欢使用gabs模块,它可以以更人性化的方式处理这些情况。
要安装模块,请使用:
go get github.com/Jeffail/gabs/v2
方便的使用示例
// jsonParsed var contains a set of functions to play arround
jsonParsed, _ := gabs.ParseJSON([]byte(`{
"outter":{
"inner":{
"value1":10,
"value2":22
},
"alsoInner":{
"value1":20,
"array1":[
30, 40
]
}
}
}`))
// for your case, it's useful Exists or ExistsP functions
exists := jsonParsed.Exists("outter", "inner", "value1")
// exists == true
exists = jsonParsed.ExistsP("outter.inner.value3")
// exists == false
当您需要一些动态键搜索时,您可以使用 ChildrenMap 函数通过前面解释的函数迭代和验证键的存在。
jsonParsed, err := gabs.ParseJSON([]byte(`{"object":{"first":1,"second":2,"third":3}}`))
if err != nil {
panic(err)
}
// S is shorthand for Search
for key, child := range jsonParsed.S("object").ChildrenMap() {
fmt.Printf("key: %v, value: %v\n", key, child.Data().(float64))
// here you can use Exists or ExistsP
}
// key: first, value: 1
// key: second, value: 2
// key: third, value: 3
- 2 回答
- 0 关注
- 116 浏览
添加回答
举报