Копирование всех элементов карты в другую
дано
var dst, src map[K]V
Я могу скопировать все записи из src
на dst
делать
for k, v := range src {
dst[k] = v
}
есть ли более идиоматические способ сделать это?
copy
работает только на ломти (и string
как источник).
3 ответа:
Это выглядит как совершенно прекрасный способ сделать это со мной. Я не думаю, что копирование одной карты в другую достаточно распространено, чтобы иметь однострочное решение.
использовать простой
for range
петля является наиболее эффективным решением.обратите внимание, что встроенный
copy
не удалось просто скопировать памятьsrc
в адресdst
потому что они могут иметь совершенно разные разметки памяти. Карты растут, чтобы вместить количество элементов, хранящихся в них. Так, например, если у вас есть карта с миллионом элементов, она занимает гораздо больше памяти, чем недавно созданная новая карта, и поэтому встроеннаяcopy
не удалось просто скопировать память без выделения новый.если ваша карта большая, Вы можете ускорить копирование элементов, если вы можете создать карту назначения, имеющую достаточно большую емкость, чтобы избежать повторного хэширования и перераспределения (начальная емкость не ограничивает ее размер), например:
dst := make(map[K]V, len(src)) for k, v := range src { dst[k] = v }
если производительность не является проблемой (например, вы работаете с маленькой карты), общее решение может быть создано с помощью
reflect
пакет:func MapCopy(dst, src interface{}) { dv, sv := reflect.ValueOf(dst), reflect.ValueOf(src) for _, k := range sv.MapKeys() { dv.SetMapIndex(k, sv.MapIndex(k)) } }
это решение не проверяет, являются ли аргументы действительно карты и если пункт назначения не
nil
. Тестирование его: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)
выход (попробуйте его на Go Playground):
map[1:one 2:two] map[one:1 two:2]
вы могли бы использовать 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}