Rubyn #injection / #reduce enumerable methods in under 5 minutes
aloittaakseen tämä menetelmä vaatii joukon ja kaksi argumenttia, kun se määritellään. Tämä voidaan visualisoida seuraavasti:
.inject { |memo, value|
#more lines of code here
}.reduce { |memo, value|
#more lines of code here
}
huomatakseen, että muuttujaamemo
tässä kutsutaan memo
muistille. Tämä muuttuja on välttämätöntä, koska se tallentaa mitä tietoja haluat tämän menetelmän muistaa, kun se kulkee koko array, mutta, se voidaan nimetä mitä haluat, koska se on vain muuttuja.
viittaan siihen nimellämemo
koko tämän selityksen ajan.
memo
voidaan antaa lähtöarvo, mutta sitä ei tarvitse olla. Jos lähtöarvoa ei ole määritelty, niin memo
ottaa joukon ensimmäisen arvon.
### 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
palauttaa aina yhden tietoobjektin — tieto memo
pitää lopussa. Tästä huolimatta memo
on muutettava ja palautettava sitä silmukoitaessa tai muuten se pysyy samassa arvossa.
nyt kun saatiin semantiikka alas, käyn läpi muutamia esimerkkejä, kun huomasin #inject
#reduce
hyödylliseksi.
Esimerkki 1: Käyttämällä #injection/#reduce numeerista operaatiota
yleisin tapa käyttää tätä menetelmää on, kun annetaan joukko kokonaislukuja ja sinun on sovellettava numeerista operaatiota koko matriisille. Tässä esimerkissä aion näyttää, miten löytää summa koko array.
#inject
#reduce
, kuvitetaan näin:
.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
koska tämä on melko yleinen tapa käyttää #inject
#reduce
, on olemassa pikakirjoitustapa, jota voit käyttää, jos haluat vain soveltaa numeerista operaatiota koko ryhmässäsi ilmaisemalla sen seuraavalla tavalla:
## This is for product, with no initial value stated
.inject(:*)
#=> 120 ### This is for sum, with an initial value of 5
.reduce(5, :+)
#=> 20
esimerkki 2: käyttämällä #injurce/ #reduce löytää pisin merkkijono
tässä esimerkissä sanotaan, että sinulle annetaan joukko merkkijonoja ja sinun täytyy löytää pisin merkkijono kyseisestä ryhmästä.
tällöin #inject
#reduce
näytetään näin:
sentences = sentences.inject{ |memo, sentence|
if memo.size < sentence.size
memo = sentence
else
memo
end
}
#=> "There are jumping lizards on the fountain"
tämän hajottamiseksi: koska emme alustakaan memo
arvo, se ottaa joukon ensimmäisen objektin, sentences
tässä esimerkissä. Menetelmämme sisällä on if
lausuma, joka vain vertaa memo
length kuhunkin sentence
length.
Tämä if
lausuma on, missä taika tapahtuu: jos sentence
on pitempi kuin memo
, annetaan memo uudelleen sentence
; muuten vain palautetaan sama arvo.
näin memo
arvo päivittyy jatkuvasti pidemmälläsentence
ja #inject
#reduce
palaa, että memo
muuttuja lopussa.
Jos haluat nähdä jokaisen vaiheen kuvitettuna, voit suorittaa tämän Repl.it katsomaan itse.
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
}
esimerkki #3: Käyttämällä #pistää / #vähentää löytää toistuvin numero array
nyt kun olemme harjoitelleet käyttää tätä menetelmää eri tavoin, tehdään samanlainen esimerkki. Sano, että sinulle annetaan satunnainen joukko numeroita ja haluat löytää, mikä numero toistuu enemmän.
Tällöin voit käyttää#inject
#reduce
näin:
numbers = numbers.reduce { |memo, number|
if numbers.count(memo) <= numbers.count(number)
memo = number
else
memo
end
}
nyt tämä logiikka on samanlainen kuin esimerkissä 2, ainoa ero on meidän if-lausekkeessamme, käytämme #count
meidän alkurivistössämme etsimään ja tallentamaan, mikä arvo on suurempi tai yhtä suuri. Näin meille palautetaan vain se määrä,jolla on lopulta suurin määrä.