1 回答
TA贡献1807条经验 获得超9个赞
只需创建一个基于模板和源地图“克隆”地图的功能。
该解决方案将遍历模板映射的条目,并为每一(k, v)
对在目标映射中生成一个条目,如下所示:
如果不是映射,只需从源映射中
v
获取键的值,并在目标中使用它。k
如果
v
也是一个地图,则递归地调用此“克隆器”,新模板地图是v
,新源是键的源的值k
。k
此递归调用的结果将是目标映射中键的值。
这就是它的样子:
func procMap(tmpl, src map[string]interface{}) (dst map[string]interface{}) {
dst = map[string]interface{}{}
for k, v := range tmpl {
if innerMap, ok := v.(map[string]interface{}); ok {
dst[k] = procMap(innerMap, src[k].(map[string]interface{}))
} else {
dst[k] = src[k]
}
}
return dst
}
就这样。
测试它:
// tmpljson is the template JSON
var tmpl map[string]interface{}
if err := json.Unmarshal([]byte(tmpljson), &tmpl); err != nil {
panic(err)
}
// srcjson is the source JSON
var src map[string]interface{}
if err := json.Unmarshal([]byte(srcjson), &src); err != nil {
panic(err)
}
dst := procMap(tmpl, src)
enc := json.NewEncoder(os.Stdout)
enc.SetIndent("", " ")
if err := enc.Encode(dst); err != nil {
panic(err)
}
使用示例 JSON 输出(在Go Playground上尝试):
{
"id": "831",
"options": {
"leatherseats": "black",
"sunroof": "full"
}
}
笔记:
该解决方案假定源映射符合模板。也就是说,如果模板包含某个键的映射,则源映射也应包含相同键的映射。如果不能保证这一点,procMap()则应通过检查来扩展该函数以避免运行时恐慌,如下所示:
for k, v := range tmpl {
if innerMap, ok := v.(map[string]interface{}); ok {
if src2, ok2 := src[k].(map[string]interface{}); ok2 {
dst[k] = procMap(innerMap, src2)
} else {
log.Printf("src is not conform to template at key %q", k)
}
} else {
dst[k] = src[k]
}
}
另请注意,JSON 数组(切片)不会以任何特殊方式处理,这意味着如果模板包含切片,则源中的值将按原样使用,如果切片包含映射,则不会发生递归。
- 1 回答
- 0 关注
- 117 浏览
添加回答
举报