The reduce() method does not return an array, it works differently than the other methods.
We use reduce() when we need to analyze all of the elements in an array and return just a single value, it can transform the data from the array into a number, string, or object.
The reducer function is always taking from the two elements (the accumulator and the current value) reducing them into one value. The thing we combine element by element is the accumulator, and the output of that combination is used with the next element to combine those two into one.
Let’s try out the reduce method with two exercises.
First exercise (apple pastry)
Here goes the story I made up:
A human (male or female) enters an old-fashioned bakery, the human immediately smells the cinnamon and thinks of apple pastry (hey, it’s true, apple and cinnamon are a perfect match), but he does not know how many pastries are made with apples, he asks the seller how many delicious products are made with apples? The seller turns to the shelf and he sees the following products:
Now, let’s help the seller and calculate the total sum of apple pastry with the reduce method:
If we console.log(apples) we will get the number 3. What happened here?
First, we set the reduce() to the array, in the condition we specify to return the accumulator and increase it by one only if the word apple exists in any of the strings.
Note the 0 (zero) before closing the function? That’s the initial value of the accumulator. It is optional, if we do not set anything then the value will be always the first count.
The accumulator is 0, it finds the string “apple tart” and the value of 1 is stored in the accumulator, okay, so now the accumulator is 1. It goes again and finds the string “apple pie” so now the accumulator is 2, again finds the “apple crumble” and now the accumulator is 3.
Okay, good, you might say we can achieve the same with the for loop, but what if in the future time, we want to know the total price of all the apple pastries? If we have an array of all the prices but you want to get a single value or total of all the prices?
This time, the result will be different, let’s see how will be stored in the accumulator?
If we console log we will get a total of 39, how come?
- In the beginning, the accumulator is 0 (the initial value is set to 0).
- The callback starts for each element and sums the accumulator with the first element in the array, 0+1 = 1, so now the accumulator is 1.
- Again, it executes the callback and sums up with the second element in the array 1 + 3, now the accumulator is 4.
- Goes again and sums with the third element 4+5 = 9,
- The fourth element sums 9+10 = 19.
- In the end, we sum with the last element 19 + 20 = 39.
I hope this clears up and makes sense, let’s continue with another exercise.
Second Exercise (two to one)
Take 2 strings
s2 including only letters from
z. Return a new sorted string, the longest possible, containing distinct letters, each taken only once — coming from s1 or s2.
Examples of the final result are below:
Honestly, this can be solved in various ways. But, let’s try and use
reduce(). For me, it is a perfect example to put reduce in action, let’s do it.
First, what are distinct letters?
A distinct letter is considered a letter that is not equal to any letter present in the set. For example, in the word “banana” the letters b, a, and n are distinct letters. Let’s say that a distinct letter is basically a unique letter.
Let’s dissect this one:
We create the function longest that will keep the logic, we create a variable
allLetters that will sum up both strings, with the inbuilt
split() the method we set each letter of the sum in an array, basically we create a new array. Remember, for the
reduce() we need to have and access an array.
distinctLetters[currentLetter] = true;
Bracket notation allows us to create a property on an object and the current letter will be each individual letter.
We reduce if the accumulator is equal to the given letter if we do not see the letter again in the string that it is a unique or distinct letter and we store the letter in the object as such. In the end, we return the letter as a distinct letter.
We set the initial value as an empty object. Because no
initialValue is provided, then
accumulator will be equal to the first value in the array, and
currentValue will be equal to the second.
In an object we have a key and value, the key is the distinct letter while the value can be true, therefore, the
Object.keys() will shoot out all the keys from the object, all distinct letters.
In the end, we use the inbuilt
sort() method and we sort the keys in the object or the letters alphabetically, in the end, we concatenate the letters with the inbuilt
join() method and return it to a string.
For me, the reduce method is the most versatile method, ever.
If you wish you can solve and find the kata here: https://www.codewars.com/kata/two-to-one
What about the reduceRight() method?
Well, that method goes the opposite, rather than starting from the first value it starts from the last value or backward.
- You forgot to add the initial, the default value (always pass a default value for the accumulator).
- You forgot to return the accumulator.
Until next time, happy coding!