Cap. 6 - Hashes
Anterior Índice Próximo
Hashes...
Mesmo que os arrays forneçam uma boa forma de indexar uma coleção de itens por número, há
situações que seria mais conveniente indexar de alguma outra forma. Se, por exemplo, você for
criar uma coleção de receitas, seria mais significativo ter cada receita indexada pelo nome tal como
“Bolo de Chocolate” e “Salada Mista” em vez de números: 23, 87 e assim por diante.
O Ruby têm uma classe que permite você fazer exatamente isso: Ela é chamada de Hash. Isto é o
equivalente ao que outras linguagens chamam de “Dicionário (Dictionary)”. Como um dicionário
real, as entradas são indexadas por alguma chave única ( num dicionário, seria uma palavra ) e um
valor ( num dicionário, seria a definição da palavra ).
hash1.r b
# Ruby Sample program from www.sapphiresteel.com /
www.bitwisemag.com
h1 = { 'room1'=>'The Treasure Room',
'room2'=>'The Throne Room',
'loc1'=>'A Forest Glade',
'loc2'=>'A Mountain Stream' }
class X
def initialize( aName )
@name = aName
end
end
x1 = X.new('my Xobject')
h2 = Hash.new("Some kind of ring")
h2['treasure1'] = 'Silver ring'
h2['treasure2'] = 'Gold ring'
h2['treasure3'] = 'Ruby ring'
h2['treasure4'] = 'Sapphire ring'
h2[x1] = 'Diamond ring'
h3 = {
'treasure3'=>'Ruby ring',
Pág. 55
Pequeno Livro do Ruby Cap. 6 Hashes
'treasure1'=>'Silver ring',
'treasure4'=>'Sapphire ring',
'treasure2'=>'Gold ring'
}
p(h2) # inspect Hash
puts(h1['room2']) # get value using a key ('The Throne
Room')
p(h2['treasure1']) # get value using a key ('Silver
ring')
p(h1['unknown_room']) # returns default value (nil)
p(h2['unknown_treasure']) # returns default value ('Some kind
of ring')
p(h1.default) #=> nil
p(h2.default) #=> 'Some kind of ring'
h1.default = 'A mysterious place'
puts(h1.default) #=> 'A mysterious place'
p(h2[x1]) # here key is object, x1; value is
'Diamond ring'
Criando Hashes
Você pode criar um hash criando uma nova instância da classe Hash:
h1 = Hash.new
h2 = Hash.new("Some kind of ring")
Ambos os exemplos acima criam um Hash vazio. Um objeto Hash sempre têm um valor padrão –
isto é, um valor que é retornado quando nenhum valor específico é encontrado em um dado índice.
Nestes dois exemplos, h2 é inicializado com o valor padrão, “Some kind of ring”; h1 não é
inicializado com um valor então seu valor padrão será nil.
Tendo criado um objeto Hash, você pode adicionar itens a ele usando uma sintaxe semelhante à dos
arrays – isto é, colocando um índice nos colchetes e usando o sinal de igual = para atribuir um
valor.
A diferença óbvia aqui é que, com um array, o índice ( a chave ) deve ser um número inteiro; com
um Hash, ele pode ser qualquer item de dado único:
h2['treasure1'] = 'Silver ring'
h2['treasure2'] = 'Gold ring'
Pág. 56
Pequeno Livro do Ruby Cap. 6 Hashes
h2['treasure3'] = 'Ruby ring'
h2['treasure4'] = 'Sapphire ring'
Muitas vezes, a chave pode ser um número ou, como no código acima, uma string. Por princípio,
uma chave pode ser qualquer tipo de objeto. Dada alguma classe, X, a seguinte atribuição é
perfeitamente legal:
x1 = X.new('my Xobject')
h2[x1] = 'Diamond ring'
Existe uma forma abreviada de criar Hashes e inicializálos com pares chavevalor. Adicione a
chave seguida por => e o valor associado; cada par chavevalor deve ser separado por uma vírgula
e o lote todo colocado entre os sinais de chaves {}:
h1 = { 'room1'=>'The Treasure Room',
'room2'=>'The Throne Room',
'loc1'=>'A Forest Glade',
'loc2'=>'A Mountain Stream' }
Chaves Únicas? Tome cuidado quando atr ibuir chaves par a Hashes. Se
você usar a mesma chave duas vezes em um Hash, você acabar á
sobr escr evendo o valor or iginal. É a mesma coisa que atr ibuir duas
vezes um valor par a o mesmo índice de um ar r ay. Consider e este
exemplo:
h2['treasure1'] = 'Silver ring'
h2['treasure2'] = 'Gold ring'
h2['treasure3'] = 'Ruby ring'
h2['treasure1'] = 'Sapphire ring'
Aqui a chave ‘tr easur e1’ foi usada duas vezes. Como conseqüência, o
valor or iginal, ‘Silver r ing’ foi substituído por ‘Sapphir e r ing’,
r esultando neste Hash:
{"treasure1"=>"Sapphire ring",
"treasure2"=>"Gold ring",
"treasure3"=>"Ruby ring"}
Indexando em um Hash
Para acessar um valor, coloque sua chave entre colchetes:
puts(h1['room2']) #=> ‘The Throne Room’
Se você especificar uma chave que não existe, o valor padrão é retornado. Lembre que nós não
especificamos um valor padrão para h1 mas o fizemos para h2:
p(h1['unknown_room']) #=> nil
p(h2['unknown_treasure']) #=> 'Some kind of ring'
Use o método default para pegar o valor padrão e o método default= para atribuilo (veja o
Capítulo 4 para mais informações sobre métodos get e set):
p(h1.default)
h1.default = 'A mysterious place'
hash2.r b
# Ruby Sample program from www.sapphiresteel.com /
www.bitwisemag.com
h1 = {'key1'=>'val1', 'key2'=>'val2', 'key3'=>'val3',
'key4'=>'val4'}
h2 = {'key1'=>'val1', 'KEY_TWO'=>'val2', 'key3'=>'VALUE_3',
'key4'=>'val4'}
p( h1.keys & h2.keys )
p( h1.values & h2.values )
p( h1.keys+h2.keys )
p( h1.valuesh2.values )
p( (h1.keys << h2.keys) )
p( (h1.keys << h2.keys).flatten.reverse )
Operações Hash
Os métodos keys e values do Hash retornam um array logo você pode usar vários métodos Array
methods para manipulálos. Aqui estão uns poucos exemplos (note, os dados mostrados nos
comentários começando por #=> mostram os valores retornados quando cada peça de código é
executada):
h1 = {'key1'=>'val1', 'key2'=>'val2', 'key3'=>'val3',
'key4'=>'val4'}
h2 = {'key1'=>'val1', 'KEY_TWO'=>'val2', 'key3'=>'VALUE_3',
'key4'=>'val4'}
p( h1.keys & h2.keys ) # set intersection (keys) #=> ["key1",
"key3", "key4"]
p( h1.values & h2.values ) # set
intersection (values)
#=> ["val1", "val2", "val4"]
p( h1.keys+h2.keys ) #
concatenation
#=> [ "key1", "key2", "key3", "key4", "key1", "key3", "key4",
"KEY_TWO"]
p( h1.valuesh2.values ) #
difference
#=> ["val3"]
p( (h1.keys << h2.keys) ) # append
#=> ["key1", "key2", "key3", "key4", ["key1", "key3", "key4",
"KEY_TWO"] ]
p( (h1.keys << h2.keys).flatten.reverse ) # ‘unnest’ arrays and
reverse
#=> ["KEY_TWO", "key4", "key3", "key1", "key4", "key3", "key2",
"key1"]
Atenção ao notar a diferença entre concatenar usando + para adicionar o valor de um segundo array
ao primeiro array e anexar usando << para adicionar o segundo array como o último elemento do
primeiro array:
a =[1,2,3]
b =[4,5,6]
c=a+b #=> c=[1, 2, 3, 4, 5, 6] a=[1,
2, 3]
a << b #=> a=[1, 2, 3, [4, 5, 6]]
Pág. 59
Pequeno Livro do Ruby Cap. 6 Hashes
Adicionalmente, << modifica o primeiro (o ‘recebedor’) array mas o + retorna um novo array
deixando o array recebedor inalterado. Se, após anexar um array com << você decide que gostaria
de adicionar os elementos do array anexado ao recebedor em vez de anexar o array propriamente
'aninhado' dentro do recebedor, você pode fazer isto usando o método flatten:
a=[1, 2, 3, [4, 5, 6]]
a.flatten #=> [1, 2, 3, 4, 5, 6]
Anterior Índice Próximo
--
LeandroNunes - 18 Oct 2006