Articles

begrip van Ruby ‘ s #inject / #reduce enumerable methods in minder dan 5 minuten

om te beginnen, heeft deze methode een array en twee argumenten nodig wanneer deze zijn gedefinieerd. Dit kan als volgt worden gevisualiseerd:

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

om op te merken, wordt de variabelememo hier wordt memo genoemd om te staan voor geheugen. Deze variabele is essentieel omdat het slaat welke gegevens u wilt dat deze methode te onthouden, terwijl het doorkruist door de array, maar het kan worden genoemd alles wat je wilt, omdat het gewoon een variabele.

Ik zal het refereren alsmemo in deze uitleg.

memo kan een startwaarde krijgen, maar het is niet vereist om er een te hebben. Als een beginwaarde niet gedefinieerd is, dan neemt memo de eerste waarde van de array.

### 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#reducegeeft altijd een enkel gegevensobject terug — de gegevens memo houdt aan het einde. Dat gezegd hebbende, memo moet worden gewijzigd en geretourneerd als het wordt lused of anders zal het op dezelfde waarde blijven.

nu we de semantiek onder de knie hebben, ga ik enkele voorbeelden doornemen voor toen ik #inject#reduce nuttig vond.

Voorbeeld 1: het gebruik van #inject / # reduce om een numerieke operatie toe te passen

de meest gebruikelijke manier om deze methode te gebruiken is wanneer u een array van gehele getallen krijgt en u een numerieke operatie op de gehele array moet toepassen. In dit voorbeeld ga ik laten zien hoe je de som van een hele array kunt vinden.

#inject#reduce , zal geïllustreerd worden dan zo uit:

.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

Aangezien dit een vrij veel voorkomende manier om te gebruiken #inject#reduce , er is een verkorte methode die u kunt gebruiken als u alleen wilt toepassen op een numerieke bewerking in uw array door te stellen dat het de volgende manier:

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

Voorbeeld 2: het Gebruik van #injecteren/ #verminder de langste tekenreeks vinden

Voor dit voorbeeld, dat u wordt gegeven een array van strings en je hebt de langste tekenreeks vinden in de matrix.

voor dit geval wordt #inject#reduce als volgt weergegeven:

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

om dit op te splitsen: aangezien we memo niet initialiseren met een waarde, zal het nodig zijn het eerste object in de array, sentences in dit voorbeeld. Binnen onze methode hebben we een if statement dat onze memo lengte vergelijkt met elke sentence lengte.

dit if statement is waar de magie gebeurt: als een sentence langer is dan degene die is opgeslagen in memo dan wijzen we memo opnieuw toe aan sentence; anders geeft u dezelfde waarde terug.

op deze manier zal onze memo waarde continu worden bijgewerkt met de langeresentence en #inject#reduce zal die memo variabele aan het einde teruggeven.

Als u elke stap geïllustreerd wilt zien, kunt u dit uitvoeren in Repl.it om het zelf te zien.

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
}

Voorbeeld # 3: Gebruik #inject / # reduce om het meest herhalende getal in een array

te vinden nu we deze methode op verschillende manieren hebben geoefend, laten we een vergelijkbaar voorbeeld doen. Stel dat u een willekeurige reeks getallen krijgt en u wilt vinden welk getal meer herhaalt.

in dit geval kunt u#inject#reduce als zodanig gebruiken:

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

nu is deze logica vergelijkbaar met wat we deden in Voorbeeld 2, het enige verschil is in ons if statement, we gebruiken #count op onze initiële array om te vinden en op te slaan welke waarde een groter of gelijk aantal heeft. Op deze manier krijgen we alleen het nummer terug dat uiteindelijk de grootste telling heeft.