Articles

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#reducemindig 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 hosszabbsentenceand #inject#reducevisszaadja ezt memová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.