首页 > 解决方案 > 在 golang 中动态创建嵌套地图

问题描述

我正在尝试在 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 对象。

有人能帮忙吗?如果我还不够清楚,请告诉我!

标签: jsongo

解决方案


通常,对于这种情况,您必须使用json.Unmarshalinto的通用解组功能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
}

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


推荐阅读