Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
向Golang中的嵌套映射[string]接口{}添加属性_Go - Fatal编程技术网

向Golang中的嵌套映射[string]接口{}添加属性

向Golang中的嵌套映射[string]接口{}添加属性,go,Go,我正在处理map[string]接口{}类型的数据。它可以在(map[string]interface{})类型中有无限数量的嵌套对象 编辑:此数据来自mongodb。我不能在这里真正应用golang的结构,因为每个文档的属性都不同。我所要做的就是获取嵌套最深的对象,向其添加一个新属性,并确保之后更新整个数据对象 这些数据来自远程API,我不知道其中的属性。我想添加的只是在最后一个对象中添加新属性(在本例中为“分数”),假设使用这个新属性(“物理”),数据将如下所示 data["person"]

我正在处理
map[string]接口{}
类型的数据。它可以在(map[string]interface{})类型中有无限数量的嵌套对象

编辑:此数据来自mongodb。我不能在这里真正应用golang的结构,因为每个文档的属性都不同。我所要做的就是获取嵌套最深的对象,向其添加一个新属性,并确保之后更新整个数据对象

这些数据来自远程API,我不知道其中的属性。我想添加的只是在最后一个对象中添加新属性(在本例中为“分数”),假设使用这个新属性(“物理”),数据将如下所示

data["person"] = map[string]interface{}{
    "peter": map[string]interface{}{
        "scores": map[string]interface{}{
            "calculus": 88,
            "algebra":  99,
            "golang":   89,
            "physics":  95,
        },
    },
}
我不确定如何将该属性添加到最后一个对象

我做了递归类型检查,能够得到每个字段并打印其值。但是,因为映射不是引用的,所以当我使用非复杂类型的值访问映射时,无法向原始映射添加值

package main

import "fmt"

func main() {

    data := make(map[string]interface{})
    data["person"] = map[string]interface{}{
        "peter": map[string]interface{}{
            "scores": map[string]interface{}{
                "calculus": 88,
                "algebra":  99,
                "golang":   89,
            },
        },
    }

    parseMap(data)
}


func parseMap(aMap map[string]interface{}) interface{} {
    var retVal interface{}

    for _, val := range aMap {
        switch val.(type) {
        case map[string]interface{}:
            retVal = parseMap(val.(map[string]interface{}))
        //case []interface{}:
        //  retVal = parseArray(val.([]interface{}))
        default:
            //here i would have done aMap["physics"] = 95 if I could access the original map by reference, but that is not possible

            retVal = aMap

        }
    }

    return retVal
}

尽量避免使用原始
map[string]接口{}
类型。Go
encoding/json
文件可以很好地处理字符串键控的映射,希望远程API能够为您处理的内容提供某种规范。(例如,您知道您希望在层次结构中的特定点上有一个
person
顶级键和
分数。)

我假设远程API是HTTP上的JSON。您可以将其结构建模为

type Input struct {
    Person map[string]Person `json:"person"`
}

type Person struct {
    Scores map[string]int `json:"scores"`
}
一旦
json.Unmarshal()
ed数据到这个结构中,就可以直接设置

data.Person["peter"].Scores["physics"] = 95
然后再次执行
json.Marshal()
结果。有一个完整的例子

如果您真的想直接操作
map[string]接口{}
结构,我建议将每个“级别”拆分为单独的函数调用

func ParseTopLevel(data map[string]interface{}) {
    switch peter := data["peter"].(type) {
    case map[string]interface{}:
        ParsePeter(peter)
    }
}

map
类型不同,因此当您到达堆栈底部时,可以直接设置
分数[“物理”]=95
。(在你的原始代码中,如果你不能像你建议的那样直接设置
aMap[“physics”]
,我会感到惊讶,尽管设置的内容相当不精确;比较。)

根据对这个问题的评论,目标是在嵌套最深的映射中设置一个值

使用以下函数查找最大嵌套级别的贴图。如果在最大嵌套级别有多个映射,此函数将返回这些映射中的任意一个

func findDeepest(m map[string]interface{}) (int, map[string]interface{}) {
    depth := 0
    candidate := m
    for _, v := range m {
        if v, ok := v.(map[string]interface{}); ok {
            d, c := findDeepest(v)
            if d+1 > depth {
                depth = d + 1
                candidate = c
            }
        }
    }
    return depth, candidate
}
如下所示,在深度嵌套贴图中设置值:

_, m := findDeepest(data)
m["physics"] = 95

.

显示您迄今为止尝试的代码。描述查找“最后一个对象”的逻辑。它是字典键顺序中的最后一个对象,嵌套最深的对象还是其他什么?我添加了代码来描述查找“最后一个对象”的逻辑。从代码和文字中看,您的意图并不清楚。代码试图向包含非map[string]接口{}或[]接口{}的值的映射添加值。散文说将值添加到没有复杂值的映射中。好的,上面的代码只是检查每个属性的类型。我感兴趣的是在最后一个嵌套映射中添加一个新属性。如果你事先不知道你的属性名称,这似乎是不可能的。它是宽度优先、深度优先、嵌套最深还是????。密钥是如何排序的?我不能在这里真正应用结构,因为数据是mongo文档,我不知道它有什么属性。谢谢Cerise Limon!但是为什么需要
深度
变量?如果没有它,它似乎可以正常工作。深度变量用于选择任何子贴图中包含的最深贴图。样本数据不需要这个变量,因为每个级别最多有一个嵌套映射。好的,我明白了。谢谢想知道,当同一级别上有兄弟对象时会发生什么。@pro如果在最大嵌套级别上有多个映射,此函数将返回这些映射中的任意一个。
_, m := findDeepest(data)
m["physics"] = 95