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 chave­valor. Adicione a chave seguida por => e o valor associado; cada par chave­valor 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 atribui­lo (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.values­h2.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.values­h2.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 ) # ‘un­nest’ 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
Topic revision: r1 - 05 Jul 2008, UnknownUser
This site is powered by FoswikiCopyright © by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding Wiki-Colivre? Send feedback