2010-12-10 59 views
0

Donc, c'est une question triviale, mais j'espère amusant. Je dois faire un Hash avec des clés et des valeurs identiques à partir des clés d'un Hash existant. Voici une entrée exemple avec ma meilleure tentative à ce jour:Comment utiliser les clés d'un Hash pour créer un nouveau Hash où la valeur de chaque clé est la clé elle-même?

input = {'cat' => 'meow', 'dog' => nil} 
Hash[*input.keys.map {|k| [k,k]}.flatten] 
#=> {'cat' => 'cat', 'dog' => 'dog'} 

Je ne pense pas que ce soit particulièrement lisible, donc je me demandais s'il y avait une meilleure syntaxe plus expressive pour ce faire en Ruby, en particulier un qui pourrait être plus lisible pour les futurs programmeurs qui maintiennent le code?

Voilà comment je ferais la même chose en Python, et je trouve qu'il est un peu plus lisible:

dict([[a,a] for a in input]) 

Mais cela pourrait être juste parce que je suis habitué à lire Python!

Vous cherchez des suggestions qui fonctionneront avec Ruby 1.8.6, qui est la version à laquelle je suis contraint.

+0

duplication possible de [Comment copier un hachage dans Ruby?] (Http://stackoverflow.com/questions/4157399/how-do-i-copy-a-hash-in-ruby) –

+0

la sortie désirée démontre que je ne demande PAS comment copier un hachage, je le transforme en un nouveau hash basé sur une fonction. J'accepterais volontiers des modifications au titre de la question pour le rendre plus clair, mais c'est un problème difficile à exprimer de façon concise. – Prairiedogg

+0

"Utilisez les touches d'un Hash pour créer un nouveau Hash où la valeur de chaque clé est elle-même." – zetetic

Répondre

3
h = {'cat' => 'meow', 'dog' => nil} 
#=> {"cat"=>"meow", "dog"=>nil} 
Hash[h.keys.map{|k| [k,k]}] 
#=> {"cat"=>"cat", "dog"=>"dog"} 

Voici une autre, un peu sale chemin (et je pense que cela fonctionne en 1.8.6):

h.merge(h){|k,v,v| k} 
+0

Excellente réponse, mais j'ai oublié de mentionner que je suis contraint de ruby ​​1.8.6, qui n'a apparemment pas cette syntaxe de création 'Hash'. Votre réponse fonctionne parfaitement en rubis 1.8.7, mais échoue en rubis 1.8.6 – Prairiedogg

+0

Ah, je vois. Jetez un oeil à 'backports' gem puis, je m'attendrais à ce que cette fonctionnalité soit incluse là. –

+0

Cela fonctionne, et indique la brièveté ... qu'est-ce qui est "sale" à ce sujet? Y a-t-il là un piège dont je devrais m'inquiéter? – Prairiedogg

2
Hash[input.keys.zip(input.keys)] #=> {"cat"=>"cat", "dog"=>"dog"} 

Ou avec inject:

input.keys.inject({}) { |h, k| h[k] = k ; h } #=> {"cat"=>"cat", "dog"=>"dog"} 

Le second aussi fonctionne en 1.8.6.