compreendendo o # injecte / # reduza os métodos enumeráveis em menos de 5 minutos
para iniciar, este método leva um array e dois argumentos quando definidos. Isto pode ser visualizado como o seguinte:
.inject { |memo, value|
#more lines of code here
}.reduce { |memo, value|
#more lines of code here
}
em nota, a variávelmemo
aqui é chamado de memo
suporte para memória. Esta variável é essencial porque armazena os dados que você quer que este método se lembre enquanto percorre todo o array, mas, ele pode ser nomeado qualquer coisa que você quiser, uma vez que é apenas uma variável.
I will be referring to it asmemo
throughout this explanation.
memo
pode ser dado um valor inicial, mas não é necessário ter um. Se um valor inicial não for definido, então memo
toma o primeiro valor do array.
### The starting value for memo is 5
.inject(5) { |memo, value|
#more lines of code here
}
### The starting value for memo is 1 (first value of the array)
.reduce { |memo, value|
#more lines of code here
}
#inject
#reduce
sempre irá retornar um único objeto de dados — os dados memo
detém no final. Dito isto, memo
tem que ser alterado e devolvido como está sendo looped ou então ele vai ficar no mesmo valor.
Now that we got the semantics down, i’m going to run through some examples for when I found #inject
#reduce
útil.
Exemplo 1: Usando #injetar / #reduzir para aplicar uma operação numérica
A maneira mais comum de usar este método é quando dado um array de inteiros e você tem que aplicar uma operação numérica em toda a matriz. Neste exemplo, vou mostrar como encontrar a soma de uma matriz inteira.
#inject
#reduce
, vai ser ilustrado como:
.reduce { |memo, value|
memo += value
} ## The following is to illustrate how this method was traversed
~> 1 += 2 #memo returns 3
~> 3 += 3 #memo returns 6
~> 6 += 4 #memo returns 10
~> 10 += 5 #memo returns 15#=> 15
uma vez que esta é uma bela forma comum de usar #inject
#reduce
há um atalho para método que você pode usar se você quiser apenas para aplicar uma operação numérica ao longo de sua matriz, informando-a da seguinte forma:
## This is for product, with no initial value stated
.inject(:*)
#=> 120 ### This is for sum, with an initial value of 5
.reduce(5, :+)
#=> 20
Exemplo 2: Usando #injetar/ #reduzir para encontrar a seqüência mais longa
neste exemplo, digamos que você está dado uma matriz de seqüências de caracteres e você tem que encontrar a seqüência mais longa na matriz.
Para este caso, #inject
#reduce
irá ser exibido da seguinte forma:
sentences = sentences.inject{ |memo, sentence|
if memo.size < sentence.size
memo = sentence
else
memo
end
}
#=> "There are jumping lizards on the fountain"
Para quebrar esse baixo: Desde que nós não inicializar memo
com um valor, ele vai levar o primeiro objeto na matriz, sentences
neste exemplo. Dentro do nosso método, temos um if
declaração de que apenas compara o nosso memo
comprimento para cada sentence
comprimento.
Thisif
statement is where the magic happens: se um sentence
for mais longo do que o armazenado em memo
então repassamos memo para ser sentence
; caso contrário, apenas devolver o mesmo valor.
Desta forma, o nosso memo
será o valor de uma atualização contínua, com a maissentence
e #inject
#reduce
vai retornar memo
variável no final.se quiser ver cada passo ilustrado, pode executá – lo em Repl.it para ver por si mesmo.
sentences = sentences.inject { |memo, sentence|
puts "Memo length is: #{memo.length}\nSentence length is: #{sentence.length}"
if memo.length < sentence.length
puts "Our sentence is longer"
memo = sentence
else
puts "Our memo is longer"
memo
end
puts "Our memo is: #{memo}\n \n"
memo
}
exemplo # 3: Usando #injecte / # reduce para encontrar o número mais repetitivo em um array
Agora que praticamos usando este método de maneiras diferentes, vamos fazer um exemplo semelhante. Digamos que lhe é dada uma matriz aleatória de Números e que quer encontrar que Número repete mais.
Para este caso, você pode usar#inject
#reduce
como assim:
numbers = numbers.reduce { |memo, number|
if numbers.count(memo) <= numbers.count(number)
memo = number
else
memo
end
}
Agora, essa lógica é semelhante ao que fizemos no Exemplo 2, a única diferença é na nossa instrução se, nós usamos #count
na nossa matriz inicial para localizar e armazenar o valor que tem um maior ou igual contagem. Desta forma, somos devolvidos apenas o número que tem a maior contagem no final.