Arquivo da categoria ‘Ruby Tips’
Ruby Tips: Iterando em Arrays
Ruby sempre me atraiu pela facilidade com que posso usar as classes Array e Hash para manter estruturas de dados que em outras linguagens eu teria a necessidade de usar classes especiais, normalmente um classe para cada tipo de elemento, o que sempre deixava o código cheio de typecasts e muitos laços FOR ou WHILE para fazer iterações. Diferente de outras linguagens, em Ruby tudo é um objeto, inclusive um Array, que possui métodos que auxiliam na própria iteração com seus elementos. Todos esses métodos de iteração recebem um bloco de código que é executado para cada elemento do Array. Vou mostrar alguns exemplos de uso abaixo, então abra o IRB e vamos testar cada um deles:
numbers = [1, 2, 3, 4, 5]
Vou usar esse array como padrão para os exemplos.
Método Each
O método EACH recebe um bloco de código que será executado para cada elemento do Array. Cada elemento é passado para o bloco como parâmetro durante a iteração. Com isso podemos realizar operação com cada elemento, como por exemplo, imprimir uma frase com cada valor:
numbers.each do |number|
puts "Linha de numero #{number}"
end
Produzirá:
Linha de numero 1
Linha de numero 2
Linha de numero 3
Linha de numero 4
Linha de numero 5
Método Select
O método SELECT recebe um bloco de código que é executado para cada elemento. A diferença com o EACH é que enquanto este não retorna nenhum valor, o SELECT retorna um outro Array. Vamos comparar a utilização dos dois com um exemplo de seleção de números pares:
even = [] numbers.each do |number| even < < number if number %2 == 0 end
Adicionamos ao Array even números com o resto da divisão por 2 igual a zero, obtendo [2,4]. Vejamos como o SELECT torna isso ainda mais fácil:
even = numbers.select do |number| number % 2 ==0 end
Método Inject
O método INJECT também chama um bloco de código para cada iteração, mas com a diferença de passar 2 parâmetros a esse bloco. O primeiro deles é um acumulador e o segundo é o elemento. Vamos novamente comparar sua utilização com o EACH com um exemplo onde somamos todos os valores do Array numbers, primeiro usando o EACH e depois usando o INJECT:
sum = 0 numbers.each do |number| sum += number end sum = numbers.inject do |a, number| a + number end
O INJECT pode ainda receber um parâmetro, que é usado como valor inicial para o acumulador. Exemplo:
sum = numbers.inject(10) do |a, number| a + number end
Com o valor inicial sendo 10, sum passaria a ter o valor 25.
Método Map
O método MAP realiza a mesma iteração em um bloco de código como nos métodos anteriores, mas a resposta é um novo Array, com novos elementos baseado em operações aplicadas a cada elemento. Desta vez vamos comparar sua utilização com o EACH criando um Array com os valores de numbers multiplicados por 10.
new_numbers = [] numbers.each do |number| new_numbers < < number * 10 end new_numbers = numbers.map do |number| number * 10 end
Depois de qualquer uma das chamadas acima, new_numbers será [10,20,30,40,50]. Logicamente o uso do método MAP neste caso é mais limpo e elegante.
Espero que tenha esclarecido a diferença de uso dos iteradores de Array existentes em Ruby. Lembrando que esses mesmos métodos também existem em classes Hash. Tecnicamente a única diferença entre Arrays e Hashs é que na primeira classe os índices dos elementos são números inteiros, enquanto que um Hash por ter qualquer tipo de objeto como índice.
Fonte: RailsSpikes
Deixe um comentário




