Comprensione di Ruby # inject / # reduce enumerable methods in meno di 5 minuti
Per iniziare, questo metodo richiede un array e due argomenti quando definito. Questo può essere visualizzato come segue:
.inject { |memo, value|
#more lines of code here
}.reduce { |memo, value|
#more lines of code here
}
Da notare, la variabilememo
qui è chiamatamemo
per rappresentare la memoria. Questa variabile è essenziale perché memorizza i dati che si desidera che questo metodo ricordi mentre attraversa l’array, ma può essere chiamato tutto ciò che si desidera poiché è solo una variabile.
Mi riferirò ad esso comememo
in tutta questa spiegazione.
memo
può essere dato un valore iniziale ma non è necessario averne uno. Se un valore iniziale non è definito, memo
prende il primo valore dell’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
restituirà sempre un singolo oggetto dati — i datimemo
rimangono alla fine. Detto questo, memo
deve essere modificato e restituito mentre viene eseguito il loop altrimenti rimarrà allo stesso valore.
Ora che abbiamo ottenuto la semantica verso il basso, ho intenzione di eseguire alcuni esempi per quando ho trovato #inject
#reduce
utile.
Esempio 1: Utilizzo di #inject/#reduce per applicare un’operazione numerica
Il modo più comune per utilizzare questo metodo è quando viene assegnato un array di numeri interi e si deve applicare un’operazione numerica sull’intero array. In questo esempio, ho intenzione di mostrare come trovare la somma di un intero array.
#inject
#reduce
, verrà illustrato come segue:
.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
Dal momento che questo è un bel modo comune di usare #inject
#reduce
c’è un metodo più breve è possibile utilizzare se si desidera applicare un’operazione numerica per tutto l’array, affermando che modo seguente:
## This is for product, with no initial value stated
.inject(:*)
#=> 120 ### This is for sum, with an initial value of 5
.reduce(5, :+)
#=> 20
Esempio 2: Utilizzo di #iniettare/ #ridurre a trovare la stringa più lunga
Per questo esempio, diciamo che si è dato un array di stringhe e devi trovare la stringa più lunga dell’array.
Per questo caso, #inject
#reduce
verrà visualizzato in questo modo:
sentences = sentences.inject{ |memo, sentence|
if memo.size < sentence.size
memo = sentence
else
memo
end
}
#=> "There are jumping lizards on the fountain"
rompere questo in giù: non siamo in grado di inizializzare memo
con un valore, sta andando a prendere il primo oggetto nell’array, sentences
in questo esempio. All’interno del nostro metodo abbiamo un’istruzione if
che confronta semplicemente la nostra lunghezza memo
con ogni lunghezza sentence
.
Questa istruzione if
è dove avviene la magia: se unsentence
è più lungo di quello memorizzato inmemo
, allora riassegniamo il memo comesentence
; altrimenti restituiamo lo stesso valore.
in Questo modo, il nostro memo
valore in continuo aggiornamento con le piùsentence
e #inject
#reduce
restituirà il memo
variabile alla fine.
Se vuoi vedere ogni passaggio illustrato, puoi eseguirlo in Repl.it per vedere di persona.
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
}
Esempio #3: Usando # inject / # reduce per trovare il numero più ripetuto in un array
Ora che abbiamo praticato l’uso di questo metodo in modi diversi, facciamo un esempio simile. Dì che ti viene data una serie casuale di numeri e vuoi trovare quale numero ripete di più.
Per questo caso, puoi usare#inject
#reduce
in questo modo:
numbers = numbers.reduce { |memo, number|
if numbers.count(memo) <= numbers.count(number)
memo = number
else
memo
end
}
Ora, questa logica è simile a quella che abbiamo fatto nell’esempio 2, l’unica differenza è nella nostra istruzione if, usiamo #count
sul nostro array iniziale per trovare e memorizzare quale valore ha un conteggio maggiore o uguale. In questo modo ci viene restituito solo il numero che ha il maggior conteggio alla fine.