A Ruby #inject / #reduce enumerable metódusainak megértése kevesebb mint 5 perc alatt
a kezdéshez ez a metódus egy tömböt és két argumentumot vesz fel, ha meg van határozva. Ez a következőképpen jeleníthető meg:
.inject { |memo, value|
#more lines of code here
}.reduce { |memo, value|
#more lines of code here
}
megjegyzendő, hogy amemo
változót itt memo
a memória rövidítése. Ez a változó elengedhetetlen, mert tárolja, hogy milyen adatokat szeretne ez a módszer emlékezni, miközben áthalad az egész tömb, de, meg lehet nevezni, amit akar, mivel ez csak egy változó.
erre a magyarázatramemo
hivatkozni fogok.
memo
megadható kezdő érték, de nem szükséges, hogy legyen. Ha nincs megadva kezdőérték, akkor amemo
a tömb első értékét veszi fel.
### 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
mindig egyetlen adatobjektumot ad vissza — az adatok memo
a végén marad. Ennek ellenére a memo
– et meg kell változtatni és vissza kell adni, ahogy hurkolják, különben ugyanazon az értéken marad.
most, hogy megvan a szemantika le, megyek fut át néhány példát, amikor találtam #inject
#reduce
hasznos.
1.példa: a #inject / #reduce használata numerikus művelet alkalmazásához
ennek a módszernek a leggyakoribb módja, ha egész számok tömbjét adjuk meg, és numerikus műveletet kell alkalmazni a teljes tömbön. Ebben a példában megmutatom, hogyan lehet megtalálni egy teljes tömb összegét.
#inject
#reduce
, így lesz szemléltetve:
.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
mivel ez egy nagyon gyakori módja a #inject
#reduce
, van egy gyorsírási módszer, amelyet akkor használhat, ha csak numerikus műveletet szeretne alkalmazni a tömbben a következő módon:
## This is for product, with no initial value stated
.inject(:*)
#=> 120 ### This is for sum, with an initial value of 5
.reduce(5, :+)
#=> 20
2.példa: a #inject/ #reduce használatával keresse meg a leghosszabb karakterláncot
ebben a példában mondjuk, hogy egy sor karakterláncot kap, és meg kell találnia a leghosszabb karakterláncot a tömbben.
ebben az esetben a #inject
#reduce
így jelenik meg:
sentences = sentences.inject{ |memo, sentence|
if memo.size < sentence.size
memo = sentence
else
memo
end
}
#=> "There are jumping lizards on the fountain"
ennek lebontásához: mivel nem inicializáljuk a memo
egy érték, ez lesz az első objektum a tömbben, sentences
ebben a példában. A módszerünkön belül van egyif
utasítás, amely csak összehasonlítja amemo
hosszunkat mindensentence
hossz.
Ez a if
utasítás az, ahol a varázslat történik: ha egysentence
hosszabb, mint amemo
akkor újra hozzárendeljük a memo-tsentence
; különben csak ugyanazt az értéket adja vissza.
ily módon a memo
érték folyamatosan frissül a hosszabbsentence
and #inject
#reduce
visszaadja ezt memo
változó a végén.
ha az egyes lépéseket illusztrálni szeretné, akkor ezt Repl.it hogy lásd magad.
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
}
3. példa: A #inject/#reduce használatával keresse meg a tömbben a leggyakrabban ismétlődő számot
most, hogy ezt a módszert különböző módon gyakoroltuk, tegyünk egy hasonló példát. Tegyük fel, hogy véletlenszerű számtömböt kapsz, és meg akarod találni, hogy melyik szám ismétlődik többet.
ebben az esetben használhatja a#inject
#reduce
like so:
numbers = numbers.reduce { |memo, number|
if numbers.count(memo) <= numbers.count(number)
memo = number
else
memo
end
}
Ez a logika hasonló ahhoz, amit a 2.példában tettünk, az egyetlen különbség az if utasításunkban van, a #count
a kezdeti tömbben Keressük és tároljuk, hogy melyik érték nagyobb vagy egyenlő. Így csak azt a számot adjuk vissza, amelynek a végén a legnagyobb a száma.