用于两个json格式的字符串合并,当B向A合并时,共有的字段,将用B字段的值(伴随类型一起覆盖),非共有的,A的字段保留,B的字段新增。
example代码:
package main import ( "encoding/json" "fmt" ) type S struct { A uint32 `json:"a"` B string `json:"b"` C uint32 `json:"c"` } type S1 struct { B string `json:"b"` C uint32 `json:"c"` D uint32 `json:"d"` } func main() { s := S{ A: 12, C: 2, } s1 := S1{ B: "123", C: 99999, D: 10, } js, _ := json.Marshal(s) js1, _ := json.Marshal(s1) var m map[string]interface{} json.Unmarshal(js, &m) json.Unmarshal(js1, &m) res, _ := json.Marshal(m) fmt.Println(string(res)) // {"a":12,"b":"123","c":99999,"d":10} }
ref:https://stackoverrun.com/cn/q/11154146
这样的方法无法递归合并,新方法可递归:
package main import ( "encoding/json" "fmt" "reflect" ) var jsonMergeDepth = 32 func main() { buf1 := []byte(`{"a":1,"b":2}`) buf2 := []byte(`{"c":3,"d":4,"a":"aaa"}`) var m1, m2 map[string]interface{} json.Unmarshal(buf1, &m1) json.Unmarshal(buf2, &m2) merged := JsonMerge(m1, m2) fmt.Println(merged) } func JsonMerge(dst, src map[string]interface{}) map[string]interface{} { return jsMerge(dst, src, 0) } func jsMerge(dst, src map[string]interface{}, depth int) map[string]interface{} { if dst == nil { dst = make(map[string]interface{}) } if depth > jsonMergeDepth { return dst // panic("too deep!") } for key, srcVal := range src { if dstVal, ok := dst[key]; ok { srcMap, srcMapOk := jsMapify(srcVal) dstMap, dstMapOk := jsMapify(dstVal) if srcMapOk && dstMapOk { srcVal = jsMerge(dstMap, srcMap, depth+1) } } dst[key] = srcVal } return dst } func jsMapify(i interface{}) (map[string]interface{}, bool) { value := reflect.ValueOf(i) if value.Kind() == reflect.Map { m := map[string]interface{}{} for _, k := range value.MapKeys() { m[k.String()] = value.MapIndex(k).Interface() } return m, true } return map[string]interface{}{}, false }