มีวิธีที่ง่ายหรือสง่าในการรวมสองแฮชโดยไม่ต้องเขียนทับคีย์ซ้ำหรือไม่?
นั่นคือถ้ากุญแจมีอยู่ในแฮชดั้งเดิมฉันไม่ต้องการเปลี่ยนค่าของมัน
มีวิธีที่ง่ายหรือสง่าในการรวมสองแฮชโดยไม่ต้องเขียนทับคีย์ซ้ำหรือไม่?
นั่นคือถ้ากุญแจมีอยู่ในแฮชดั้งเดิมฉันไม่ต้องการเปลี่ยนค่าของมัน
คำตอบ:
หากคุณมีแฮชสองครั้งoptions
และdefaults
และคุณต้องการรวมdefaults
เข้าด้วยกันoptions
โดยไม่ต้องเขียนทับคีย์ที่มีอยู่สิ่งที่คุณต้องการทำจริงๆคือการย้อนกลับ: รวมoptions
เข้ากับdefaults
:
options = defaults.merge(options)
หรือถ้าคุณใช้ Rails คุณสามารถทำได้:
options.reverse_merge!(defaults)
reverse_merge!
ลดค่าลงเนื่องจากปัญหาด้านความปลอดภัยในราง 5.1
มีวิธีหนึ่งในไลบรารี Ruby มาตรฐานที่จะรวมแฮชโดยไม่เขียนทับค่าที่มีอยู่หรือกำหนดแฮชใหม่
important_hash.merge!(defaults) { |key, important, default| important }
หากปัญหาของคุณคือการแฮชดั้งเดิมและคีย์ที่สองทั้งคู่อาจมีคีย์ที่ซ้ำกันและคุณไม่ต้องการเขียนทับในทิศทางใดทิศทางหนึ่งคุณอาจต้องไปรวมด้วยตนเองอย่างง่ายพร้อมการตรวจสอบการชนและการจัดการบางอย่าง:
hash2.each_key do |key|
if ( hash1.has_key?(key) )
hash1[ "hash2-originated-#{key}" ] = hash2[key]
else
hash1[key]=hash2[key]
end
end
เห็นได้ชัดว่านี่เป็นพื้นฐานมากและถือว่า hash1 ไม่มีคีย์ใด ๆ ที่เรียกว่า "hash2 ที่มาจากอะไรก็ตาม" - คุณอาจจะดีกว่าแค่เพิ่มตัวเลขลงในคีย์ดังนั้นมันจึงกลายเป็น key1, key2 และอื่น ๆ จนกว่าคุณจะกด อันที่ไม่ได้อยู่ใน hash1 นอกจากนี้ฉันยังไม่ได้ทับทิมใด ๆ มาสองสามเดือนดังนั้นนั่นอาจไม่ถูกต้องทางไวยากรณ์ แต่คุณควรจะได้รับส่วนสำคัญ
หรือกำหนดค่าของคีย์เป็นอาร์เรย์อีกครั้งเพื่อให้ hash1 [key] ส่งคืนค่าดั้งเดิมจาก hash1 และค่าจาก hash2 ขึ้นอยู่กับสิ่งที่คุณต้องการให้ผลลัพธ์ของคุณเป็นจริง
ที่นี่คุณสามารถรวม 2 แฮชของคุณโดย reverse_merge
order = {
id: 33987,
platform: 'web'
}
user = {
name: 'Jhon Doe',
email: 'jhon.doe@gmail.com'
}
newHash = oder.reverse_merge!(user)
render json: { data: newHash, status: 200 }
หากคุณต้องการรวมสองแฮชoptions
และdefaults
โดยไม่ต้องเขียนทับแฮชปลายทางคุณอาจตรวจสอบselect
ว่ามีคีย์อยู่ในแฮชปลายทางแล้วหรือไม่ นี่คือโซลูชัน Ruby บริสุทธิ์ที่ไม่มี Rails:
options = { "a" => 100, "b" => 200 }
defaults = { "b" => 254, "c" => 300 }
options.merge!(defaults.select{ |k,_| not options.has_key? k })
# output
# => {"a"=>100, "b"=>200, "c"=>300}
หรือถ้ามีคีย์ แต่มีnil
และคุณต้องการเขียนทับมัน:
options.merge!(defaults.select{ |k,_| options[k].nil? })