î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
#reduce
va 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ă.