ฉันจะรวมพจนานุกรมสองเล่มใน Vim ได้อย่างไร


9

ฉันมีสอง dicts:

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

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

ฉันจะรวมกุญแจเข้าด้วยกันอย่างไรoverrideเพื่อที่ฉันจะได้ลงท้ายด้วยพจน์ใหม่เช่น:

{'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 ไปยังฟังก์ชั่นเนื่องจากมันถูกส่งผ่านโดยการอ้างอิง (ดังนั้นมันจะถูกแก้ไขนอกฟังก์ชั่นด้วย)


โปรดทราบว่าจะไม่รวมการผสานซ้อนกันซึ่งอาจเป็นสิ่งที่ดีหรือไม่ขึ้นอยู่กับสิ่งที่คุณกำลังมองหา:

: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()หากคุณต้องการแก้ไขในสถานที่ (เร็วขึ้นเล็กน้อย แต่อาจไม่คาดคิด)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.