p hash.values.flatten
# => [Autor: Mauricio Aniche, Isbn: 123454, Páginas: 247,
Categoria: testes,
Autor: Tárcio Zemel, Isbn: 452565, Páginas: 189,
Categoria: web_design]
O método flatten procura por objetos do tipo Array dentro do Array
onde o método foi chamado (em nosso exemplo o Array retornando pelo método
values), extrai esses valores e retorna um novo Array com todos os elementos
extraídos. É importante ressaltar que o método flatten é recursivo, se o invocar-
mos em um Array, que possui vários outros objetos do tipo Array, que por sua
vez sejam formados por alguns outros objeto que também sejam Array, ele recur-
sivamente extrairá os elementos de todos eles e retornará os elementos em um novo
objeto Array.
teste_e_design = Livro.new "Mauricio Aniche", "123454", 247, 60.9,
:testes
57
4.5. Indo mais a fundo: Hashes no Ruby 1.9
Casa do Código
web_design_responsivo = Livro.new "Tárcio Zemel", "452565", 189, 70.9,
:web_design
jsf_e_jpa = Livro.new "Gilliard Cordeiro", "543465", 234, 64.9,
:frameworks_mvc
hash = {}
hash[:testes] = [ [ teste_e_design ], [ jsf_e_jpa ] ]
hash[:web_design] = [ [ web_design_responsivo ] ]
p hash.values.flatten
# => [Autor: Mauricio Aniche, Isbn: 123454, Páginas: 247,
Categoria: testes,
Autor: Gilliard Cordeiro, Isbn: 543465, Páginas: 234,
Categoria: frameworks_mvc,
Autor: Tárcio Zemel, Isbn: 452565, Páginas: 189,
Categoria: web_design]
4.5
Indo mais a fundo: Hashes no Ruby 1.9
A chave identificadora de um objeto Hash pode ser um
objeto de qualquer tipo
( String, Integer, Livro, etc). Porém o mais comum é definirmos as chaves
como Symbol, que são comumente utilizados para esta finalidade. Por exemplo:
teste_e_design = Livro.new "Mauricio Aniche", "123454", 247, 60.9,
:testes
web_design_responsivo = Livro.new "Tárcio Zemel", "452565", 189, 70.9,
:web_design
hash = { :testes => [teste_e_design],
:web_design => [web_design_responsivo] }
p hash[:testes] # => ["Autor: Mauricio Aniche, Isbn: 123454,
Páginas: 247,
Categoria: :testes"]
Na versão 1.9 da linguagem Ruby foi introduzida uma nova sintaxe para declarar
elementos em um hash quando a chave identificadora é um Symbol, muito parecida
com a sintaxe da linguagem Javascript. Entretanto a forma que acessamos o valor de
Hash continua sendo a mesma:
58
Casa do Código
Capítulo 4. Estruturas de dados
teste_e_design = Livro.new "Mauricio Aniche", "123454", 247, 60.9,
:testes
web_design_responsivo = Livro.new "Tárcio Zemel", "452565", 189, 70.9,
:web_design
hash = { testes: [teste_e_design], web_design: [web_design_responsivo] }
p hash[:testes] # => ["Autor: Mauricio Aniche, Isbn: 123454,
Páginas: 247,
Categoria: :testes"]
4.6
Indo mais a fundo: O operador ||=
Imagine que queremos setar o valor em uma determinada variável somente se o valor
atual da mesma for nil, caso ela já esteja preenchida, o valor deve ser mantido:
idade = nil
idade = 27 unless idade
puts idade # 27
idade = 35 unless idade
puts idade # 27
Muito código para uma tarefa trivial. Por isso, os criadores do Ruby, fizeram o
operador ||=, que executa o mesmo comportamento que implementamos com o
unless:
idade = nil
idade ||= 27
puts idade # 27
idade ||= 35
puts idade # 27
4.7
Indo mais a fundo: O tipo Set
Quando trabalhamos com objeto do tipo Array, podemos repetir os mesmos ele-
mentos quantas vezes acharmos necessário, por exemplo:
numeros = [1, 2, 2, 3, 2, 1]
p numeros # [1, 2, 2, 3, 2, 1]
59
4.7. Indo mais a fundo: O tipo Set
Casa do Código
Não existe nenhuma regra que proíba a duplicidade de elementos. Mas em certas
ocasiões é necessário garantirmos que dentro de uma estrutura de dados existam
elementos únicos, ou seja, sem repetição. Ruby contempla essa necessidade através
de um outro tipo de coleção, chamada Set, que guarda valores em um ordem não
definida (diferente de arrays) e garante a não duplicidade.
A sintaxe usada para criarmos uma coleção do tipo Set é um pouco diferente
das que vimos até o momento:
require 'set'
numero_sem_repeticao = Set.new [1, 2, 2, 3, 2, 1]
Quando precisamos utilizar o tipo Set, precisamos carregar o arquivo set.rb
que foi instalado junto com o interpretador e as outras classes básicas da própria
linguagem. O arquivo set.rb contém a classe Set.
A classe Set possui um método initialize que recebe um Array com os
elementos que formarão a coleção, ao receber este array, são guardados apenas os
elementos não repetidos e descartados os restantes. Podemos verificar este compor-
tamento iterando no Set que foi criado:
require 'set'
numero_sem_repeticao = Set.new [1, 2, 2, 3, 2, 1]
for numero in numero_sem_repeticao do
p numero
end
# => 1
# => 2
# => 3
Vimos que a classe Set consegue descobrir quais são os elementos iguais e
manter apenas um destes elementos. Isso funciona muito bem com os números, mas
e se tentarmos adicionar várias instância de um mesmo Livro dentro de um Set.
Vamos ver?
require 'set'
teste_e_design = Livro.new "Mauricio Aniche", "123454", 247, 60.9,