У меня есть рекурсивная функция, которая создает объекты, представляющие пути к файлам (ключи - это пути, а значения - информация о файле). Это рекурсивно, поскольку предназначено только для обработки файлов, поэтому, если обнаружен каталог, функция рекурсивно вызывается в каталоге.
Все, что было сказано, я хотел бы сделать эквивалент объединения наборов на двух картах (то есть «основная» карта, обновленная значениями из рекурсивного вызова). Есть ли идиоматический способ сделать это, кроме итерации по одной карте и присвоения каждого ключа, значения в нем тому же самому элементу на другой карте?
То есть: с учетом a,b
имеют тип map [string] *SomeObject
, а a
и b
в конечном счете населены, есть ли способ обновления a
со всеми значениями в b
?
Ответы:
В стандартных пакетах нет встроенного способа или какого-либо метода для такого слияния.
Идоматический способ - просто повторить:
for k, v := range b { a[k] = v }
источник
a[k] = v
наa[k] = a[k] + v
или что-то в этом роде.a[k] = append(a[k], v...)
Если у вас есть несколько вложенных карт,
left
иright
эта функция будет рекурсивно добавлять элементы изright
вleft
. Если ключ ужеleft
введен, мы углубляемся в структуру и пытаемся только добавить ключиleft
(например, никогда не заменять их).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 }
ПРИМЕЧАНИЕ. Я не рассматриваю случаи, когда само значение не является a
map[string]interface{}
. Так что, если у вас есть,left["x"] = 1
аright["x"] = 2
затем приведенный выше код вызовет панику при попыткеleftVal.(m)
.источник