2009-12-30 3 views
111

Existe-t-il un moyen simple ou de combiner élégamment deux hachages sans écraser les clés en double? En d'autres termes, si la clé est présente dans le hachage d'origine, je ne souhaite pas en modifier la valeur.Comment puis-je fusionner deux hachages sans doublons écrasés dans Ruby?

+0

Voulez-vous dire vraiment des tableaux (par exemple: [ 'a', 'b', 'c']) ou hash (par exemple: { 'a' => 1, 'b' => 2, « c '=> 3})? –

+0

Désolé, je parlais de hashes :) –

Répondre

178

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: fusionner options en defaults:

options = defaults.merge(options) 

Ou , si vous utilisez Rails vous pouvez faire:

options.reverse_merge!(defaults) 
+0

Tout à fait d'accord, merci beaucoup pour reverse_merge! méthode ne le savait pas :) –

+0

WHY est-il besoin de parenthèses ici? Vous ne pouvez pas faire des options default.merge il apparaît. – Donato

4

Si vos problèmes est que le hachage original et le second les deux peuvent avoir des clés en double et vous ne voulez pas écraser dans les deux sens, vous pourriez avoir à passer pour un simple fusion manuelle avec une sorte de vérification de collision et de manutention:

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, ce qui est très rudimentaire et suppose que hash1 n'a pas de clés appelées « hash2 -originée-quoi que ce soit "- il vaudrait peut-être mieux ajouter un nombre à la clé pour qu'elle devienne key1, key2 et ainsi de suite jusqu'à ce que vous en ayez une qui ne soit pas déjà dans hash1. De plus, je n'ai pas fait de rubis depuis quelques mois, donc ce n'est probablement pas correct sur le plan syntaxique, mais vous devriez être capable de comprendre l'essentiel.

Vous pouvez également redéfinir la valeur de la clé en tant que 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 que votre résultat soit vraiment.

+0

Que diriez-vous de ne pas garder les deux clés, mais en additionnant les valeurs de la même clé? –

+1

@ TomK.C.Chiu Cela dépend beaucoup des circonstances que nous ne pouvons pas juger à partir de la question - que se passe-t-il si les valeurs dans hash1 sont des chaînes et hash2 sont des entiers? Dans certains cas, cela pourrait être une option viable, mais le plus souvent cela causerait des problèmes - la suggestion d'utiliser des listes de valeurs fonctionne très bien autour de cela. – glenatron

13

Il existe un moyen dans la bibliothèque Ruby standard de fusionner des hachages sans écraser les valeurs existantes ou réaffecter le hachage.

important_hash.merge!(defaults) { |key, important, default| important } 
Questions connexes