¿Existe una manera fácil o elegante de combinar dos hashes sin sobrescribir las claves duplicadas?
Es decir, si la clave está presente en el hash original, no quiero cambiar su valor.
¿Existe una manera fácil o elegante de combinar dos hashes sin sobrescribir las claves duplicadas?
Es decir, si la clave está presente en el hash original, no quiero cambiar su valor.
Respuestas:
Si tiene dos valores hash, options
y defaults
, y desea combinar defaults
en options
sin sobrescribir las claves existentes, lo que realmente quiere hacer es a la inversa: la fusión options
en defaults
:
options = defaults.merge(options)
O, si está utilizando Rails, puede hacer:
options.reverse_merge!(defaults)
reverse_merge!
debido a problemas de seguridad en los rieles 5.1
Si su problema es que el hash original y el segundo pueden tener claves duplicadas y no desea sobrescribir en ninguna dirección, es posible que deba realizar una fusión manual simple con algún tipo de control y manejo de colisiones:
hash2.each_key do |key|
if ( hash1.has_key?(key) )
hash1[ "hash2-originated-#{key}" ] = hash2[key]
else
hash1[key]=hash2[key]
end
end
Obviamente, esto es muy rudimentario y asume que hash1 no tiene ninguna tecla llamada "originada por hash2-lo que sea" - puede que sea mejor agregar un número a la tecla para que se convierta en clave1, clave2 y así sucesivamente hasta que presione uno que aún no está en hash1. Además, no he hecho ningún rubí en unos meses, por lo que probablemente no sea sintácticamente correcto, pero deberías poder entenderlo.
Alternativamente, redefina el valor de la clave como una matriz para que hash1 [clave] devuelva el valor original de hash1 y el valor de hash2. Depende de lo que quieras que sea realmente tu resultado.
Aquí puedes combinar tus 2 hash por 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 }
Si desea fusionar los dos hash options
y defaults
sin sobrescribir el hash de destino, puede verificar select
si la clave ya está presente en el hash de destino. Aquí está la solución Ruby pura sin rieles:
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}
O si la clave está presente, pero contiene nil
y desea sobrescribirla:
options.merge!(defaults.select{ |k,_| options[k].nil? })