Cómo agregar a un hash existente en Ruby

102

En lo que respecta a agregar un key => valuepar a un hash poblado existente en Ruby, estoy en el proceso de trabajar en Beginning Ruby de Apress y acabo de terminar el capítulo de hashes.

Estoy tratando de encontrar la forma más sencilla de lograr los mismos resultados con hashes que con las matrices:

x = [1, 2, 3, 4]
x << 5
p x
Tom
fuente

Respuestas:

189

Si tiene un hash, puede agregarle elementos haciendo referencia a ellos por clave:

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

Aquí, como [ ]crea una matriz vacía, { }creará un hash vacío.

Las matrices tienen cero o más elementos en un orden específico, donde los elementos pueden estar duplicados. Los hash tienen cero o más elementos organizados por clave , donde las claves no pueden estar duplicadas pero los valores almacenados en esas posiciones sí.

Los hashes en Ruby son muy flexibles y pueden tener claves de casi cualquier tipo que puedas lanzarle. Esto lo diferencia de las estructuras de diccionario que se encuentran en otros idiomas.

Es importante tener en cuenta que la naturaleza específica de la clave de un hash a menudo es 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 confunde esto un poco al proporcionar HashWithIndifferentAccess donde se convertirá libremente entre los métodos de direccionamiento Symbol y String.

También puede indexar casi cualquier cosa, incluidas clases, números u otros Hashes.

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

hash[Object]
# => true

hash[Hash]
# => false

hash[Array]
# => nil

Los hash se pueden convertir en matrices y viceversa:

# 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"} 

Cuando se trata de "insertar" cosas en un Hash, puede hacerlo de una en una, o utilizar el mergemétodo para combinar hash:

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

Tenga en cuenta que esto no altera el hash original, sino que devuelve uno nuevo. Si desea combinar un hash con otro, puede usar el merge!método:

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'}

Como muchos métodos en String y Array, !indica que es una operación local .

tadman
fuente
12
Mucha información valiosa, pero carece de la formulación más básica, como la responde tan simplemente @robbrit.
danh
1
Edite su respuesta para responder realmente la pregunta que se hizo, preferiblemente en algún lugar cerca de la parte superior. Sería de mala educación por mi parte hacerlo por ti.
Stephan
@Stephan Agregó un ejemplo más conciso en la parte superior.
tadman
64
my_hash = {:a => 5}
my_hash[:key] = "value"
robbrit
fuente
34

Si desea agregar más de uno:

hash = {:a => 1, :b => 2}
hash.merge! :c => 3, :d => 4
p hash
Josh Kovach
fuente
8
x = {:ca => "Canada", :us => "United States"}
x[:de] = "Germany"
p x
Jeremy Roman
fuente
Intenté implementar esto con lo siguiente: x['key'] = "value"sin embargo, recibo errores. Debo mencionar que estoy trabajando con cadenas.
Tom
1
Cual es el error? Podría ser cualquier cosa a menos que sea más específico.
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"} 

Devuelve el valor combinado.

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

Pero no modifica el objeto de la persona que llama

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 reasignación funciona.

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

Puede obtener su clave y valor de la entrada del usuario, por lo que puede usar Ruby .to_sym puede convertir una cadena en un símbolo, y .to_i convertirá una cadena en un número entero.
Por ejemplo:

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.
ark1980
fuente
0

Puede usar el operador de doble símbolo que está disponible desde Ruby 2.0:

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