Articles

Forstå Ruby ‘ s # inject / # reduser enumerable metoder på under 5 minutter

for å starte, tar denne metoden en matrise og to argumenter når definert. Dette kan visualiseres som følgende:

.inject { |memo, value| 
#more lines of code here
}.reduce { |memo, value|
#more lines of code here
}

for å merke seg, variabelenmemo her kalles memo å stå for minne. Denne variabelen er viktig fordi den lagrer hvilke data du vil at denne metoden skal huske mens den går gjennom hele arrayet, men det kan bli kalt alt du vil ha, siden det bare er en variabel.

jeg vil referere til det som memo gjennom denne forklaringen.

memo kan gis en startverdi, men det er ikke nødvendig å ha en. Hvis en startverdi ikke er definert, tar memo den første verdien av matrisen.

### 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 vil alltid returnere et enkelt dataobjekt — dataene memo holder på slutten. Når det er sagt, memo må endres og returneres når den blir sløyfet, ellers vil den forbli på samme verdi.

Nå som vi fikk semantikken ned, skal jeg løpe gjennom noen eksempler for når jeg fant#inject#reduce nyttig.

Eksempel 1: Bruk #inject / # reduser for å bruke en numerisk operasjon

den vanligste måten å bruke denne metoden på er når du får en rekke heltall, og du må bruke en numerisk operasjon på hele arrayet. I dette eksemplet skal jeg vise hvordan du finner summen av en hel matrise.

#inject#reduce, vil bli illustrert som sådan:

.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

Siden dette er en ganske vanlig måte å bruke #inject#reduce, det er en shorthand metode du kan bruke hvis du bare vil bruke en numerisk operasjon i hele arrayet ditt ved å si det på følgende måte:

## This is for product, with no initial value stated
.inject(:*)
#=> 120 ### This is for sum, with an initial value of 5
.reduce(5, :+)
#=> 20

eksempel 2: bruk #inject/ #reduser for å finne Den Lengste strengen

for dette eksemplet, si at du får en rekke strenger, og du må finne den lengste strengen i den arrayen.

for dette tilfellet vil #inject#reduce vises slik:

sentences = sentences.inject{ |memo, sentence| 
if memo.size < sentence.size
memo = sentence
else
memo
end
}
#=> "There are jumping lizards on the fountain"

for å bryte dette ned: siden vi ikke initialiserer memo med en verdi, det kommer til å ta det første objektet i arrayet, sentences i dette eksemplet. Innenfor vår metode har vi enif setning som bare sammenligner vår memo lengde til hver sentence lengde.

Dette if setningen er hvor magien skjer: hvis en sentence er lengre enn den som er lagret i memo så tilordner vi memo til å være sentence; ellers returnerer vi bare samme verdi.

på denne måten vil vårmemo verdien oppdateres kontinuerlig med den lengresentence og#inject#reduce vil returnere detmemo variabel til slutt.

hvis du vil se hvert trinn illustrert, kan du kjøre dette i Repl.it å se selv.

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
}

Eksempel # 3: Bruk #inject / # reduser for å finne det mest gjentatte tallet i en matrise

Nå som vi praktiserte å bruke denne metoden på forskjellige måter, la oss gjøre et lignende eksempel. Si at du får et tilfeldig utvalg av tall, og du vil finne hvilket nummer som gjentar mer.

for dette tilfellet kan du bruke #inject#reduce som så:

numbers = numbers.reduce { |memo, number|
if numbers.count(memo) <= numbers.count(number)
memo = number
else
memo
end
}

nå er denne logikken lik det Vi gjorde I Eksempel 2, den eneste forskjellen er i vår if-setning, vi bruker #count på vår første array for å finne og lagre hvilken verdi som har en større eller lik telling. På denne måten returneres vi bare nummeret som har størst telling til slutt.