Understanding Ruby ’ s #inject / # reduce enumerable methods in under 5 minutes
för att starta tar denna metod en array och två argument när de definieras. Detta kan visualiseras som följande:
.inject { |memo, value|
#more lines of code here
}.reduce { |memo, value|
#more lines of code here
}
Observera att variabelnmemo
här kallas memo
för att stå för minne. Denna variabel är viktig eftersom den lagrar vilka data du vill att den här metoden ska komma ihåg medan den går igenom hela matrisen, men den kan namnges vad du vill eftersom det bara är en variabel.
Jag kommer att hänvisa till det sommemo
genom hela denna förklaring.
memo
kan ges ett startvärde men det är inte nödvändigt att ha ett. Om ett startvärde inte är definierat tar memo
det första värdet i 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
returnerar alltid ett enda dataobjekt — data memo
håller i slutet. Med det sagt, memo
måste ändras och returneras när den slingras, annars kommer den att förbli på samma värde.
Nu när vi har semantiken nere, kommer jag att springa igenom några exempel för när jag hittade #inject
#reduce
användbar.
exempel 1: Använda #inject / #reduce för att tillämpa en numerisk operation
det vanligaste sättet att använda den här metoden är när du får en rad heltal och du måste tillämpa en numerisk operation på hela matrisen. I det här exemplet ska jag visa hur man hittar summan av en hel array.
#inject
#reduce
, kommer att illustreras 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
eftersom detta är ett ganska vanligt sätt att använda #inject
#reduce
, det finns en stenografi metod som du kan använda om du bara vill tillämpa en numerisk operation i hela din array genom att ange det på följande sätt:
## This is for product, with no initial value stated
.inject(:*)
#=> 120 ### This is for sum, with an initial value of 5
.reduce(5, :+)
#=> 20
exempel 2: Använda #inject/ #reduce för att hitta den längsta strängen
För det här exemplet, säg att du får en rad strängar och du måste hitta den längsta strängen i den arrayen.
För det här fallet kommer #inject
#reduce
att visas så här:
sentences = sentences.inject{ |memo, sentence|
if memo.size < sentence.size
memo = sentence
else
memo
end
}
#=> "There are jumping lizards on the fountain"
för att bryta ner detta: eftersom vi inte initierar memo
med en värde, det kommer att ta det första objektet i matrisen, sentences
I det här exemplet. Inuti vår metod har vi ettif
uttalande som bara jämför vårmemo
längd till varjesentence
längd.
dettaif
uttalande är där magin händer: om en sentence
är längre än den som lagras i memo
då vi åter tilldela memo vara sentence
; annars bara returnera samma värde.
På så sätt uppdateras vårtmemo
värde kontinuerligt med det längresentence
och#inject
#reduce
returnerar detmemo
variabel i slutet.
Om du vill se varje steg illustrerat kan du köra detta i Repl.it att se själv.
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
}
exempel # 3: Använda #inject/ # reduce för att hitta det mest upprepande numret i en array
Nu när vi övade att använda denna metod på olika sätt, låt oss göra ett liknande exempel. Säg att du får en slumpmässig uppsättning siffror och du vill hitta vilket nummer som upprepas mer.
i det här fallet kan du använda#inject
#reduce
som så:
numbers = numbers.reduce { |memo, number|
if numbers.count(memo) <= numbers.count(number)
memo = number
else
memo
end
}
nu liknar denna logik vad vi gjorde i Exempel 2, den enda skillnaden är i vårt if-uttalande, Vi använder #count
på vår ursprungliga array för att hitta och lagra vilket värde som har ett större eller lika antal. På så sätt returneras vi bara det nummer som har störst räkning i slutändan.