Articles

înțelegerea #inject / #reduce metodele enumerabile Ruby în mai puțin de 5 minute

pentru a începe, această metodă ia o matrice și două argumente atunci când sunt definite. Aceasta poate fi vizualizată după cum urmează:

.inject { |memo, value| 
#more lines of code here
}.reduce { |memo, value|
#more lines of code here
}

pentru a nota, variabilamemo aici se numește memo pentru a reprezenta memoria. Această variabilă este esențială, deoarece stochează ce date doriți ca această metodă să-și amintească în timp ce traversează întreaga matrice, dar poate fi numită orice doriți, deoarece este doar o variabilă.

mă voi referi la el camemo în toată această explicație.

memo poate fi dat o valoare de pornire, dar nu este necesar să aibă unul. Dacă o valoare de pornire nu este definită, atunci memo ia prima valoare a matricei.

### 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#reduceva returna întotdeauna un singur obiect de date — datele memo se păstrează la sfârșit. Acestea fiind spuse, memo trebuie schimbat și returnat pe măsură ce este buclat sau altfel va rămâne la aceeași valoare.

acum că am dat jos semantica, voi trece prin câteva exemple pentru când am găsit#inject#reduce util.

Exemplul 1: Utilizarea #inject/#reduc pentru a aplica o operație numerică

cea mai obișnuită modalitate de a utiliza această metodă este atunci când vi se oferă o matrice de numere întregi și trebuie să aplicați o operație numerică pe întreaga matrice. În acest exemplu, voi arăta cum să găsiți suma unei matrice întregi.

#inject#reduce , va fi ilustrat ca atare:

.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

deoarece acesta este un mod destul de comun de a folosi #inject#reduce , există o metodă de prescurtare pe care o puteți utiliza dacă doriți doar să aplicați o operație numerică în întreaga matrice, precizând-o în felul următor:

## This is for product, with no initial value stated
.inject(:*)
#=> 120 ### This is for sum, with an initial value of 5
.reduce(5, :+)
#=> 20

Exemplul 2: folosind #inject/ #reduce pentru a găsi cel mai lung șir

pentru acest exemplu, spuneți că vi se oferă o serie de șiruri și trebuie să găsiți cel mai lung șir din acea matrice.

pentru acest caz, #inject#reduce va fi afișat astfel:

sentences = sentences.inject{ |memo, sentence| 
if memo.size < sentence.size
memo = sentence
else
memo
end
}
#=> "There are jumping lizards on the fountain"

pentru a descompune acest lucru: deoarece nu inițializăm memo valoare, va lua primul obiect din matrice, sentences în acest exemplu. În interiorul metodei noastre avem oif declarație care doar comparămemo lungime la fiecaresentence lungime.

aceastăif declarație este în cazul în care magia se întâmplă: dacă unsentence este mai lung decât cel stocat înmemo atunci re-atribuim memo să fiesentence; altfel returnăm aceeași valoare.

în acest fel,memo valoarea noastră se va actualiza continuu cusentence și#inject#reduce va returnamemo variabilă în cele din urmă.

Dacă doriți să vedeți fiecare pas ilustrat, puteți rula acest lucru în Repl.it pentru a vedea pentru tine.

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
}

exemplu #3: Folosind # inject / # reduce pentru a găsi numărul cel mai repetat într-o matrice

acum, că am practicat folosind această metodă în moduri diferite, să facem un exemplu similar. Spuneți că vi se oferă o serie aleatorie de numere și doriți să găsiți ce număr se repetă mai mult.

pentru acest caz, puteți utiliza #inject#reduce ca așa:

numbers = numbers.reduce { |memo, number|
if numbers.count(memo) <= numbers.count(number)
memo = number
else
memo
end
}

acum, această logică este similară cu ceea ce am făcut în exemplul 2, singura diferență este în Declarația noastră if, folosim#count pe matricea noastră inițială pentru a găsi și stoca ce valoare are un număr mai mare sau egal. În acest fel ne sunt returnate doar numărul care are cel mai mare număr în cele din urmă.