Чи є простий чи елегантний спосіб об'єднати два хеши, не перезаписуючи повторювані ключі?
Тобто, якщо ключ присутній у вихідному хеші, я не хочу змінювати його значення.
Чи є простий чи елегантний спосіб об'єднати два хеши, не перезаписуючи повторювані ключі?
Тобто, якщо ключ присутній у вихідному хеші, я не хочу змінювати його значення.
Відповіді:
Якщо у вас є два хеша, options
і defaults
, і ви хочете об'єднатись defaults
у них, options
не перезаписуючи існуючі ключі, то, що ви дійсно хочете зробити, це зворотне: об'єднати options
в defaults
:
options = defaults.merge(options)
Або якщо ви використовуєте Rails, ви можете:
options.reverse_merge!(defaults)
reverse_merge!
через проблеми безпеки на рейках 5.1
Якщо ваші проблеми полягають у тому, що оригінальний хеш і другий можуть мати повторювані ключі, і ви не хочете перезаписувати в жодному напрямку, можливо, вам доведеться скористатися простим ручним злиттям з якоюсь перевіркою та обробкою зіткнення:
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 і так далі, поки ви не натиснете на той, який вже не є хеш1. Крім того, я не робив жодного рубіну протягом декількох місяців, тому це, мабуть, не синтаксично правильно, але ви повинні мати можливість отримати суть.
Альтернативно, повторно визначте значення ключа у вигляді масиву, щоб 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? })