Souza Lucas - Ruby: Aprenda a programar na linguagem mais divertida стр 18.

Шрифт
Фон

Casa do Código

cujo identificador é a String "452565", que corresponde ao isbn do ob-

jeto web_design_responsivo. Cada um destes containers possui um deter-

minado valor, no Hash acima o container 123454 possui como valor o objeto

teste_e_design, já o container, cujo identificado é 452565, possui como valor o

objeto web_design_responsivo.

Quando desejamos acessar o valor que está incluso dentro um Hash, basta in-

vocarmos o método [:chave] passando a chave identificadora do container:

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 = { "123454" => web_design_responsivo,

"452565" => web_design_responsivo }

p hash["123454"]

# => Autor: Tárcio Zemel, Isbn: 452565, Páginas: 189,

Categoria: web_design

Bem parecido com a maneira que acessamos valores dentro de um Array. A

diferença é que passamos um objeto que representa a chave identificadora, e não um

Integer que representa o índice, como acontece quando acessamos valores de um

Array.

Agora vou provar que o encapsulamento que fizemos ao definir a classe

Biblioteca nos ajudará a migrar sem sofrimentos de Array para Hash a es-

trutura que guardava os livros:

class Biblioteca

attr_reader :livros

def initialize

@livros = {} # Inicializa com um hash

end

def adiciona(livro)

@livros[livro.categoria] ||= []

@livros[livro.categoria] << livro

end

end

54

Casa do Código

Capítulo 4. Estruturas de dados

O código que instancia os livros e os guarda dentro da biblioteca, continua fun-

cionando.

biblioteca = Biblioteca.new

teste_e_design = Livro.new "Mauricio Aniche", 247, "123454",

:testes

web_design_responsivo = Livro.new "Tárcio Zemel", 189, "452565",

:web_design

biblioteca.adiciona teste_e_design

biblioteca.adiciona web_design_responsivo

O problema agora é o método que utilizamos para retornar os livros que estão

dentro da nossa biblioteca, retornam um Hash e não mais um Array e a forma de

iterar sobre estas duas estruturas de dados são diferentes. A primeira opção é fazer

com que o método livros continue retornando um Array:

class Biblioteca

def adiciona(livro)

@livros[livro.categoria] ||= []

@livros[livro.categoria] << livro

end

def livros

@livros.values.flatten

end

end

Criando nossa própria implementação do método livros, conseguimos man-

ter o mesmo comportamento anterior, quando retornávamos um array diretamente.

A segunda opção para resolver o problema, é retornar um Hash e alterar a forma

que iteramos sobre o retorno no método livros:

biblioteca = Biblioteca.new

teste_e_design = Livro.new "Mauricio Aniche",

"123454", 247, 60.9,

:testes

web_design_responsivo = Livro.new "Tárcio Zemel", "452565", 189, 70.9, 55

4.4. Como separar os livros por categoria: trabalhe com Hash

Casa do Código

:web_design

biblioteca.adiciona teste_e_design

biblioteca.adiciona web_design_responsivo

for categoria, livros in biblioteca.livros do

p categoria

for livro in livros do

p livro.valor

end

end

# => :testes

# => 60.9

# => :web_design

# => 70.9

A diferença é que o método for recebe dois argumentos, a chave e o valor do

hash. Em nosso exemplo, a chave é a categoria da estante de livros ( :testes,

por exemplo), e valor é um array com os livros desta categoria.

Os métodos values e flatten

Quando precisamos obter todos os valores de um determinado hash, indepen-

dente do container, utilizamos o método values (que retorna todos os valores do

hash dentro de um Array):

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.values # [teste_e_design, web_design_responsivo]

No caso da classe Biblioteca, nós guardamos conjuntos de livros dentro de

Array, sendo um Array para cada categoria. Quando os valores de um hash são

do tipo Array, o método values retornará um novo Array com vários Array

dentro, o que pode não ser um resultado muito interessante para trabalharmos, veja:

56

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.values

# => [Autor: Mauricio Aniche, Isbn: 123454, Páginas: 247,

Categoria: testes],

[Autor: Tárcio Zemel, Isbn: 452565, Páginas: 189,

Categoria: web_design]

Precisamos que o retorno do método livros seja um único Array com to-

dos os livros existentes dentro da Biblioteca independente da categoria deles.

Podemos alcançar nosso objetivo utilizando o método flatten:

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

Ваша оценка очень важна

0
Шрифт
Фон

Помогите Вашим друзьям узнать о библиотеке