Есть ли простой или элегантный способ объединить два хэша без перезаписи повторяющихся ключей?
То есть, если ключ присутствует в исходном хэше, я не хочу менять его значение.
Есть ли простой или элегантный способ объединить два хэша без перезаписи повторяющихся ключей?
То есть, если ключ присутствует в исходном хэше, я не хочу менять его значение.
Ответы:
Если у вас есть два хэша, options
и defaults
, и вы хотите объединить defaults
их options
без перезаписи существующих ключей, то на самом деле вы хотите сделать обратное: объединить options
в defaults
:
options = defaults.merge(options)
Или, если вы используете Rails, вы можете:
options.reverse_merge!(defaults)
reverse_merge!
из-за проблем с безопасностью в rails 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-originated-something» - вам может быть лучше просто добавить число к ключу, чтобы он стал key1, key2 и так далее, пока вы не нажмете тот, которого еще нет в hash1. Кроме того, я не использовал Ruby в течение нескольких месяцев, так что это, вероятно, синтаксически неверно, но вы должны быть в состоянии понять суть.
В качестве альтернативы переопределите значение ключа как массив, чтобы 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? })