Comment ajouter à un hachage existant dans Ruby

102

En ce qui concerne l'ajout d'une key => valuepaire à un hachage rempli existant dans Ruby, je suis en train de travailler sur Beginning Ruby d'Apress et je viens de terminer le chapitre sur les hachages.

J'essaie de trouver le moyen le plus simple d'obtenir les mêmes résultats avec les hachages qu'avec les tableaux:

x = [1, 2, 3, 4]
x << 5
p x
À M
la source

Réponses:

189

Si vous avez un hachage, vous pouvez y ajouter des éléments en les référençant par clé:

hash = { }
hash[:a] = 'a'
hash[:a]
# => 'a'

Ici, comme [ ]crée un tableau vide, { }va créer un hachage vide.

Les tableaux ont zéro ou plusieurs éléments dans un ordre spécifique, où les éléments peuvent être dupliqués. Les hachages ont zéro ou plusieurs éléments organisés par clé , où les clés ne peuvent pas être dupliquées mais les valeurs stockées dans ces positions peuvent l'être.

Les hachages en Ruby sont très flexibles et peuvent avoir des clés de presque tous les types que vous pouvez lui lancer. Cela le rend différent des structures de dictionnaire que vous trouvez dans d'autres langues.

Il est important de garder à l'esprit que la nature spécifique d'une clé de hachage est souvent importante:

hash = { :a => 'a' }

# Fetch with Symbol :a finds the right value
hash[:a]
# => 'a'

# Fetch with the String 'a' finds nothing
hash['a']
# => nil

# Assignment with the key :b adds a new entry
hash[:b] = 'Bee'

# This is then available immediately
hash[:b]
# => "Bee"

# The hash now contains both keys
hash
# => { :a => 'a', :b => 'Bee' }

Ruby on Rails confond cela quelque peu en fournissant HashWithIndifferentAccess où il convertira librement entre les méthodes d'adressage Symbol et String.

Vous pouvez également indexer sur presque tout, y compris les classes, les nombres ou d'autres hachages.

hash = { Object => true, Hash => false }

hash[Object]
# => true

hash[Hash]
# => false

hash[Array]
# => nil

Les hachages peuvent être convertis en tableaux et vice-versa:

# Like many things, Hash supports .to_a
{ :a => 'a' }.to_a
# => [[:a, "a"]]

# Hash also has a handy Hash[] method to create new hashes from arrays
Hash[[[:a, "a"]]]
# => {:a=>"a"} 

Quand il s'agit d '"insérer" des éléments dans un hachage, vous pouvez le faire un par un, ou utiliser la mergeméthode pour combiner des hachages:

{ :a => 'a' }.merge(:b => 'b')
# {:a=>'a',:b=>'b'}

Notez que cela ne modifie pas le hachage d'origine, mais en renvoie un nouveau. Si vous souhaitez combiner un hachage dans un autre, vous pouvez utiliser la merge!méthode:

hash = { :a => 'a' }

# Returns the result of hash combined with a new hash, but does not alter
# the original hash.
hash.merge(:b => 'b')
# => {:a=>'a',:b=>'b'}

# Nothing has been altered in the original
hash
# => {:a=>'a'}

# Combine the two hashes and store the result in the original
hash.merge!(:b => 'b')
# => {:a=>'a',:b=>'b'}

# Hash has now been altered
hash
# => {:a=>'a',:b=>'b'}

Comme de nombreuses méthodes sur String et Array, le !indique qu'il s'agit d'une opération sur place .

tadman
la source
12
Beaucoup d'informations précieuses, mais sans la formulation la plus basique, comme répondu simplement par @robbrit.
danh
1
Veuillez modifier votre réponse pour répondre réellement à la question qui a été posée, de préférence vers le haut. Ce serait impoli de ma part de le faire pour vous.
Stephan le
@Stephan Ajout d'un exemple plus concis en haut.
tadman
64
my_hash = {:a => 5}
my_hash[:key] = "value"
Robbrit
la source
34

Si vous souhaitez en ajouter plusieurs:

hash = {:a => 1, :b => 2}
hash.merge! :c => 3, :d => 4
p hash
Josh Kovach
la source
8
x = {:ca => "Canada", :us => "United States"}
x[:de] = "Germany"
p x
Jeremy Roman
la source
J'ai essayé de mettre en œuvre ceci avec ce qui suit: x['key'] = "value"cependant je reçois des erreurs. Je devrais mentionner que je travaille avec des chaînes.
Tom
1
Quelle est l'erreur? Cela pourrait être n'importe quoi, sauf si vous êtes plus précis.
tadman
1
hash = { a: 'a', b: 'b' }
 => {:a=>"a", :b=>"b"}
hash.merge({ c: 'c', d: 'd' })
 => {:a=>"a", :b=>"b", :c=>"c", :d=>"d"} 

Renvoie la valeur fusionnée.

hash
 => {:a=>"a", :b=>"b"} 

Mais ne modifie pas l'objet appelant

hash = hash.merge({ c: 'c', d: 'd' })
 => {:a=>"a", :b=>"b", :c=>"c", :d=>"d"} 
hash
 => {:a=>"a", :b=>"b", :c=>"c", :d=>"d"} 

La réaffectation fait l'affaire.

Raam
la source
0
hash {}
hash[:a] = 'a'
hash[:b] = 'b'
hash = {:a => 'a' , :b = > b}

Vous pouvez obtenir votre clé et votre valeur à partir de l'entrée utilisateur, vous pouvez donc utiliser Ruby .to_sym peut convertir une chaîne en symbole, et .to_i convertira une chaîne en un entier.
Par exemple:

movies ={}
movie = gets.chomp
rating = gets.chomp
movies[movie.to_sym] = rating.to_int
# movie will convert to a symbol as a key in our hash, and 
# rating will be an integer as a value.
arche1980
la source
0

Vous pouvez utiliser l'opérateur double splat disponible depuis Ruby 2.0:

h = { a: 1, b: 2 }
h = { **h, c: 3 }
p h
# => {:a=>1, :b=>2, :c=>3}
Sajad Rastegar
la source