Articles

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#reducepalauttaa 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ä.