Como adicionar a um hash existente em Ruby

102

Com relação à adição de um key => valuepar a um hash populado existente em Ruby, estou no processo de trabalhar no Apress 'Beginning Ruby e acabei de terminar o capítulo de hashes.

Estou tentando encontrar a maneira mais simples de obter os mesmos resultados com hashes e arrays:

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

Respostas:

189

Se você tiver um hash, poderá adicionar itens a ele referenciando-os por chave:

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

Aqui, como [ ]cria um array vazio, { }criará um hash vazio.

Os arrays têm zero ou mais elementos em uma ordem específica, onde os elementos podem ser duplicados. Hashes têm zero ou mais elementos organizados por chave , onde as chaves não podem ser duplicadas, mas os valores armazenados nessas posições podem ser.

Hashes em Ruby são muito flexíveis e podem ter chaves de quase qualquer tipo que você possa usar. Isso o torna diferente das estruturas de dicionário que você encontra em outros idiomas.

É importante ter em mente que a natureza específica de uma chave de hash geralmente é 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 isso um pouco, fornecendo HashWithIndifferentAccess, onde converterá livremente entre os métodos de endereçamento de símbolo e string.

Você também pode indexar em quase tudo, incluindo classes, números ou outros Hashes.

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

hash[Object]
# => true

hash[Hash]
# => false

hash[Array]
# => nil

Hashes podem ser convertidos em matrizes e 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"} 

Quando se trata de "inserir" coisas em um Hash, você pode fazer uma de cada vez ou usar o mergemétodo para combinar os hashes:

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

Observe que isso não altera o hash original, mas retorna um novo. Se quiser combinar um hash em outro, você pode usar o 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 muitos métodos em String e Array, o !indica que é uma operação local .

Tadman
fonte
12
Muitas informações valiosas, mas sem a formulação mais básica, respondida simplesmente por @robbrit.
danh
1
Edite sua resposta para realmente responder à pergunta que foi feita, de preferência em algum lugar próximo ao topo. Seria rude de minha parte fazer isso por você.
Stephan
@Stephan Adicionado um exemplo mais conciso no topo.
tadman
64
my_hash = {:a => 5}
my_hash[:key] = "value"
Robbrit
fonte
34

Se você deseja adicionar mais de um:

hash = {:a => 1, :b => 2}
hash.merge! :c => 3, :d => 4
p hash
Josh Kovach
fonte
8
x = {:ca => "Canada", :us => "United States"}
x[:de] = "Germany"
p x
Jeremy Roman
fonte
Tentei implementar isso com o seguinte: x['key'] = "value"no entanto, estou recebendo erros. Devo dizer que estou trabalhando com cordas.
Tom
1
Qual é o erro? Pode ser qualquer coisa, a menos que você seja mais 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"} 

Retorna o valor mesclado.

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

Mas não modifica o objeto chamador

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

A reatribuição resolve o problema.

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

Você pode obter sua chave e valor a partir da entrada do usuário, então pode usar Ruby .to_sym pode converter uma string em um símbolo e .to_i irá converter uma string em um inteiro.
Por exemplo:

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
fonte
0

Você pode usar o operador double splat que está disponível desde Ruby 2.0:

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