Copying all elements of a map into another

后端 未结 3 1489
长发绾君心
长发绾君心 2020-12-15 02:15

Given

var dst, src map[K]V

I can copy all entries from src into dst by doing

for k, v := range sr         


        
相关标签:
3条回答
  • 2020-12-15 02:54

    That looks like a perfectly fine way to do this to me. I don't think copying one map into another is common enough to have a one-liner solution.

    0 讨论(0)
  • 2020-12-15 02:59

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

    Note that a builtin copy could not just copy the memory of src to the address of dst because they may have entirely different memory layout. Maps grow to accommodate the number of items stored in them. So for example if you have a map with a million elements, it occupies a lot more memory than a freshly created new map, and so a builtin copy could not just copy memory without allocating new.

    If your map is big, you can speed up copying elements if you may create the destination map having a big-enough capacity to avoid rehashing and reallocation (the initial capacity does not bound its size), e.g.:

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

    If performance is not an issue (e.g. you're working with small maps), a general solution may 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 it:

    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)
    

    Output (try it on the Go Playground):

    map[1:one 2:two]
    map[one:1 two:2]
    
    0 讨论(0)
  • 2020-12-15 03:05

    You could 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}
    
    0 讨论(0)
提交回复
热议问题