Copy all map elements to another

Considering

var dst, src map[K]V 

I can copy all entries from src to dst by doing

 for k, v := range src { dst[k] = v } 

Is there a more idiomatic way to do this?

copy only works on slices (and string as a source).

+59
dictionary copy go
Sep 15 '11 at 20:08
source share
3 answers

It looks like a great way to do this with me. I do not think that copying one card to another is common enough to have a one-line solution.

+44
Sep 15 '11 at 20:17
source share

Using a simple for range loop is the most efficient solution.

Please note that the built-in copy could not just copy the src memory to the dst address, because they may have a completely different memory format. Cards grow to accommodate the number of items stored in them. So, for example, if you have a card with a million elements, it takes up much more memory than a newly created new card, and therefore the built-in copy could not just copy the memory without allocating a new one.

If your map is large, you can speed up copying of elements, if you can create a destination map that has a sufficiently large capacity to avoid re-interception and redistribution (the initial capacity does not limit its size), for example:

 dst := make(map[K]V, len(src)) for k, v := range src { dst[k] = v } 

If performance is not a problem (for example, you work with small cards), a general solution can be created using the reflect package:

 func MapCopy(dst, src interface{}) { dv, sv := reflect.ValueOf(dst), reflect.ValueOf(src) for _, k := range sv.MapKeys() { dv.SetMapIndex(k, sv.MapIndex(k)) } } 

This solution does not check if the arguments are really maps, and if the destination is not nil . Testing:

 m1 := map[int]string{1: "one", 2: "two"} m2 := map[int]string{} MapCopy(m2, m1) fmt.Println(m2) m3 := map[string]int{"one": 1, "two": 2} m4 := map[string]int{} MapCopy(m4, m3) fmt.Println(m4) 

Conclusion (try on the Go Playground ):

 map[1:one 2:two] map[one:1 two:2] 
+7
Aug 04 '15 at 10:45
source share

You can use github.com/linkosmos/mapop

 input := map[string]interface{}{ "Key1": 2, "key3": nil, "val": 2, "val2": "str", "val3": 4, } input2 := map[string]interface{}{ "a2": "str", "a3": 4, } input = mapop.Merge(input, input2) input{"Key1": 2, "key3": nil, "val": 2, "val2": "str", "val3": 4, "a2": "str", "a3": 4} 
+2
Feb 09 '16 at 3:30
source share



All Articles