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, optionset defaults, et vous souhaitez fusionner defaultsen optionssans écraser les clés existantes, ce que vous voulez vraiment faire est l'inverse: fusion optionsen 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 optionset defaultssans écraser le hachage de destination, vous pouvez vérifier avec selectsi 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 nilet que vous souhaitez l'écraser:
options.merge!(defaults.select{ |k,_| options[k].nil? })