Vim에서 두 개의 사전을 어떻게 병합합니까?


9

나는 두 가지 전략이 있습니다.

:let defaults = {'hello': 'world', 'bye': 'jupiter'}

:let override = {'hello': 'mars'}

키를 병합하여 다음 override과 같은 새로운 dict로 끝내 려면 어떻게 해야합니까?

{'hello': 'mars', 'bye': 'jupiter'}

답변:


7

당신은 사용할 수 있습니다 extend():

:let defaults = {'hello': 'world', 'bye': 'jupiter'}
:let override = {'hello': 'mars'}

:echo extend(defaults, override)
{'hello': 'mars', 'bye': 'jupiter'}

두 번째 인수의 키는 첫 번째 인수의 기존 키보다 우선합니다. defaultsDICT이 될 것입니다 장소에 수정 원되지 않을 수 있습니다. copy()이를 방지하기 위해 사용하십시오 .

:call extend(copy(defaults), override)
:echo defaults
{'hello': 'world', 'bye': 'jupiter'}

이것은 함수에 dict를 함수에 전달할 때 특히주의해야합니다. 함수에 참조로 전달되므로 함수 외부에서도 수정됩니다.


찾고있는 것에 따라 중첩 된 dicts를 병합하지 않을 것입니다.

:echo extend({'nest': {'a': 'b'}}, {'nest': {'b': 'XXXX'}})
{'nest': {'b': 'XXXX'}}

중첩 된 dicts를 재귀 적으로 병합하려면 작은 도우미 함수가 필요합니다.

" 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()제자리에서 수정하려는 경우 (약간 빠르지 만 예상치 못한) 제거 할 수 있습니다 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.