Existe-t-il un moyen simple ou élégant de fusionner deux hachages sans écraser les clés en double?
Autrement dit, si la clé est présente dans le hachage d'origine, je ne veux pas changer sa valeur.
Existe-t-il un moyen simple ou élégant de fusionner deux hachages sans écraser les clés en double?
Autrement dit, si la clé est présente dans le hachage d'origine, je ne veux pas changer sa valeur.
Réponses:
Si vous avez deux hash, options
et defaults
, et vous souhaitez fusionner defaults
en options
sans écraser les clés existantes, ce que vous voulez vraiment faire est l'inverse: fusion options
en defaults
:
options = defaults.merge(options)
Ou, si vous utilisez Rails, vous pouvez faire:
options.reverse_merge!(defaults)
reverse_merge!
raison de problèmes de sécurité dans les rails 5.1
Si votre problème est que le hachage d'origine et le second peuvent tous deux avoir des clés en double et que vous ne voulez pas écraser dans les deux sens, vous devrez peut-être opter pour une simple fusion manuelle avec une sorte de vérification et de gestion des collisions:
hash2.each_key do |key|
if ( hash1.has_key?(key) )
hash1[ "hash2-originated-#{key}" ] = hash2[key]
else
hash1[key]=hash2[key]
end
end
De toute évidence, cela est très rudimentaire et suppose que hash1 n'a pas de clé appelée "hash2-originated-what" - vous feriez peut-être mieux d'ajouter simplement un numéro à la clé pour qu'elle devienne key1, key2 et ainsi de suite jusqu'à ce que vous appuyiez sur celui qui n'est pas déjà dans hash1. De plus, je n'ai pas fait de rubis depuis quelques mois, donc ce n'est probablement pas syntaxiquement correct, mais vous devriez être en mesure de comprendre l'essentiel.
Vous pouvez également redéfinir la valeur de la clé sous forme de tableau afin que hash1 [key] renvoie la valeur d'origine de hash1 et la valeur de hash2. Cela dépend de ce que vous voulez vraiment que votre résultat soit.
Ici, vous pouvez fusionner vos 2 hachages par 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 vous souhaitez fusionner les deux hachages options
et defaults
sans écraser le hachage de destination, vous pouvez vérifier avec select
si la clé est déjà présente dans le hachage de destination. Voici la solution pure Ruby sans 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}
Ou si la clé est présente, mais contient nil
et que vous souhaitez l'écraser:
options.merge!(defaults.select{ |k,_| options[k].nil? })