У меня есть два слова:
:let defaults = {'hello': 'world', 'bye': 'jupiter'}
:let override = {'hello': 'mars'}
Как я могу объединить ключи override
так, чтобы я получил новый dict как:
{'hello': 'mars', 'bye': 'jupiter'}
У меня есть два слова:
:let defaults = {'hello': 'world', 'bye': 'jupiter'}
:let override = {'hello': 'mars'}
Как я могу объединить ключи override
так, чтобы я получил новый dict как:
{'hello': 'mars', 'bye': 'jupiter'}
Ответы:
Вы можете использовать extend()
:
:let defaults = {'hello': 'world', 'bye': 'jupiter'}
:let override = {'hello': 'mars'}
:echo extend(defaults, override)
{'hello': 'mars', 'bye': 'jupiter'}
Ключи от второго аргумента переопределяют любые существующие в первом. defaults
ДИКТ будет изменен в месте , которое не может быть желанным. Используйте copy()
для предотвращения этого:
:call extend(copy(defaults), override)
:echo defaults
{'hello': 'world', 'bye': 'jupiter'}
Это особенно важно, когда вы передаете dict функции, поскольку она передается по ссылке (поэтому она также будет изменена вне функции).
Обратите внимание, что это не объединит вложенные диктовки, что может или не может быть хорошей вещью, в зависимости от того, что вы ищете:
:echo extend({'nest': {'a': 'b'}}, {'nest': {'b': 'XXXX'}})
{'nest': {'b': 'XXXX'}}
Вам понадобится небольшая вспомогательная функция для рекурсивного объединения вложенных слов:
" Merge two dictionaries, also recursively merging nested keys.
"
" Use extend() if you don't need to merge nested keys.
fun! s:merge(defaults, override) abort
let l:new = copy(a:defaults)
for [l:k, l:v] in items(a:override)
let l:new[l:k] = (type(l:v) is v:t_dict && type(get(l:new, l:k)) is v:t_dict)
\ ? s:merge(l:new[l:k], l:v)
\ : l:v
endfor
return l:new
endfun
Вы можете удалить его, copy()
если хотите изменить его на месте (немного быстрее, но, возможно, неожиданно).