Articles

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 variabilememoqui è 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#reducerestituirà 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.