Getting the union of two maps in go

Solution 1:

There is no built in way, nor any method in the standard packages to do such a merge.

The idomatic way is to simply iterate:

for k, v := range b {
    a[k] = v
}

Solution 2:

If you have a couple of nested maps, left and right, then this function will recursively add the items from right into left. If the key is already in left then we recurse deeper into the structure and attempt only add keys to left (e.g. never replace them).


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
}

NOTE: I do not handle the case in which the value is not itself a map[string]interface{}. So if you have left["x"] = 1 and right["x"] = 2 then the above code will panic when attempting leftVal.(m).

Solution 3:

Go is limited by what type of map it is. I'd suspect that there isn't built in functions because of the infinite number of type declarations that could exist for a map. So you have to build your own Merge functions depending on what type of map you are using:

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
}