我有一个递归函数,它创建表示文件路径的对象(键是路径,值是关于文件的信息)。它是递归的,因为它仅用于处理文件,因此如果遇到目录,则在目录上递归调用该函数。
所有这一切,我想在两个地图上做相当于集合的联合(即" main"地图用递归调用的值更新)。除了迭代一个地图并将每个键,其中的值分配给另一个地图中的相同内容之外,还有一种惯用的方法吗?
即:给定的a,b
类型为map [string] *SomeObject
,最终会填充a
和b
,是否有办法更新a
b
?
答案 0 :(得分:67)
没有内置方式,也没有标准包中的任何方法来进行这样的合并。
自觉的方式是简单地迭代:
for k, v := range b {
a[k] = v
}
答案 1 :(得分:2)
如果您有几个嵌套的地图left
和right
,则此函数将把right
中的项目递归添加到left
中。如果密钥已经在left
中,那么我们会更深入地探究该结构,并仅尝试对left
进行 add 密钥(例如,永远不要替换它们)。
type m = map[string]interface{}
// Given two maps, recursively merge right into left, NEVER replacing any key that already exists in left
func mergeKeys(left, right m) m {
for key, rightVal := range right {
if leftVal, present := left[key]; present {
//then we don't want to replace it - recurse
left[key] = mergeKeys(leftVal.(m), rightVal.(m))
} else {
// key not in left so we can just shove it in
left[key] = rightVal
}
}
return left
}
注意:我不处理该值本身不是map[string]interface{}
的情况。因此,如果您有left["x"] = 1
和right["x"] = 2
,则在尝试leftVal.(m)
时,上面的代码将崩溃。
答案 2 :(得分:0)
Go 受地图类型的限制。我怀疑没有内置函数,因为地图可能存在无限数量的类型声明。因此,您必须根据您使用的地图类型构建自己的合并函数:
func MergeJSONMaps(maps ...map[string]interface{}) (result map[string]interface{}) {
result = make(map[string]interface{})
for _, m := range maps {
for k, v := range m {
result[k] = v
}
}
return result
}