Come posso unire due dizionari in Vim?


9

Ho due dicts:

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

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

Come posso unire le chiavi in overridemodo da finire con un nuovo dict in questo modo:

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

Risposte:


7

Puoi usare extend():

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

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

Le chiavi del secondo argomento hanno la precedenza su quelle esistenti nel primo. Il defaultsdict verrà modificato sul posto , che potrebbe non essere desiderato. Utilizzare copy()per evitare che:

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

Questo è particolarmente utile quando si passa un dict a una funzione, poiché viene passato per riferimento (quindi verrà modificato anche al di fuori della funzione).


Nota che non unirà i dadi annidati, il che può essere o meno una buona cosa, a seconda di ciò che stai cercando:

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

Avrai bisogno di una piccola funzione di aiuto per unire ricorsivamente i dadi annidati:

" 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

Puoi rimuoverlo copy()se vuoi modificarlo sul posto (un po 'più veloce, ma forse inaspettato).

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.