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

在golang中动态创建嵌套地图

在golang中动态创建嵌套地图

Go
慕姐8265434 2023-06-01 18:17:27
我正在尝试在 Golang 中解释 JSON。我正在搜索未知 JSON 中的特定属性,我知道它的键,但我的 JSON 可能真的是嵌套的。我确实知道我的 JSON 中有多少“层”。例如,如果我的 JSON 是:nestedJson = { key1: { key2: { key3: "Found data" } } } 我的键是 ["key1", "key2", "key3"] 并且这个 JSON 中有 3 层,所以我可以通过这样做来取回数据var nestedJson = []map[string]map[string]map[string]interface{}json.Unmarshal([]byte(nestedJon), &nestedJson)data := nestedJson["key1]["key2"]["key3"]我想要做的是通过为应该搜索的层数指定一个整数值来动态创建 nestedJson 对象。有人能帮忙吗?如果我还不够清楚,请告诉我!
查看完整描述

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

}

注意:此功能很快被破解在一起,可能会错误处理一堆极端情况。它在这里展示了关键思想 - 将其用作满足您特定需求的基础


查看完整回答
反对 回复 2023-06-01
?
四季花海

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


查看完整回答
反对 回复 2023-06-01
  • 2 回答
  • 0 关注
  • 116 浏览
慕课专栏
更多

添加回答

举报

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