Read the documentation for
If you specify a block, then for each element in enum the block is passed an accumulator value (memo) and the element...the result becomes the new value for memo. At the end of the iteration, the final value of memo is the return value for the method.
For a little added clarity, your block can be rewritten as:
words.reduce do |longest, word|
if longest.length > word.length
The block to reduce takes two parameters: the current value of the reduction (also called the memo, or accumulator), and the current element being processed. The value that the block returns is what it uses as the memo for the next iteration.
In English, your reduction here is looking at each word in the array and keeping the longest word that it sees after each iteration. The net result is that the
reduce expression used here is returning the longest word in the array, which is
If you were to step through the execution one iteration at a time, you'd see the following values being passed to the block:
- Iteration 0
longest = "cat",
word = "cat"
- An initial value was not specified for the memo, so
reduce uses the first value in the array ("cat") as the default memo
- "cat" remains our memo
- Iteration 1
longest = "cat",
word = "sheep"
- Because "sheep" is longer than "cat", "sheep" becomes our new memo
- Iteration 2
longest = "sheep",
word = "bear"
- "sheep" is longer than "bear", so it remains as our memo
- We've iterated through the entire array, and the resulting value for the
reduce call is the value of our current memo, "sheep"
Reduce is also known as folding in some languages. The term "folding" makes intuitive sense as you're rolling or folding each value in the array into some kind of aggregate (reduced) final value.