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 關注
- 164 瀏覽
添加回答
舉報