The Mutli-Tool of JS

Paul Anderson
Nov 16, 2018 · 5 min read

When it comes to reduce, there are two groups of people:

  1. I don’t know reduce well enough for it to be beneficial
  2. I wish I would have learned reduce sooner

Reduce is an incredibly power tool which can make your life easier with less code. Its flexible nature allows reduce to fill a wide range of use cases, some of which we’ll explore today.

What is Reduce

For a quick description, reduce is a function on the Array prototype which returns a value without modifying the originally provided array.

At the most basic level, reduce is a higher-order function which takes two values.

  • reducer - Function to run for each array element
  • initialValue - Starting value for the reducer (Optional)

However, without knowing what the reducer expects, the above is not very helpful. Here is the entire structure:

  • accumulator - Stores the value returned by // return logic here
  • current - Current array item
  • index - Index of the current array item
  • source - Original array provided
  • initialValue - Starting value for the accumulator. Defaults to first array item if not provided

In many scenarios, the index and source parameters are not utilized, but it’s good to know they’re available.

Also, the reducer function should always return the accumulator, even if it has not been modified.

Time to start reducing!

Counting with Reduce

Starting with a basic example, here’s a counter function that uses a for loop. It ingests an array, counts each item, and returns the sum.

Let’s achieve the same result using reduce. Below is a beginner function which includes logging to visualize the iterations.

Here’s an output of reducing numbers = [3, 4, 5]

We start with a defined accumulator of 0 (zero). Each loop, the current array item is added to the accumulator. Then, the accumulator (with its new value) is used for the next array item. This iteration continues until the entire array has been processed, resulting in a sum of 12.

Here is an advanced version of the counter. Notice how little code it uses.

You may notice this version does not provide an initialValue. Instead of starting at zero, the reducer uses the first array value of numbers[0] = 3 as a starting point. This results in the loop running twice instead of thrice:

  • Beginner: ((0 + 3) + 4) + 5
  • Advanced: (3 + 4) + 5

For more practice, all three example are available for download. Modify the file as needed and run in terminal:

node counting.js

What else can Reduce do?

So reduce can sum numbers. Can reduce count the occurrence of numbers?

Absolutely. The following example iterates on manyNumbers. Each number is evaluated using a ternary operator to check if the cur number should be added or positively incremented in acc. Then, acc is return to be used for the next iteration.

If the above is confusing, a beginner version can be found here. Below is an output for running manyNumbers.

manyNumbers = [1, 1, 2, 3, 3, 3, 4, 4, 5, 5, 5, 5, 5, 6, 7, 7, 7, 7]

Alternatively, the same idea could be used to return unique occurrences by slightly modifying the ternary operator.

What if this example was applied to a list of objects instead of a list of numbers? The possibilities are endless.

Reverse this String

To use reduce in a different way, let’s talk about reversing. Reversing a string is a programming challenge which can be solved many ways. Here’s one solution using a for loop.

Although this does reverse the string, it doesn’t use reduce. Let’s reverse a string using reduce(Right)!

reduceRight is just like reduce, but works the array from right to left, instead of left to right. The below ingests a string, splits the string into an array, and combines the array values from right to left.

If you’re confused with this one, download the example, uncomment reduceReverseBeginner, and follow the log outputs.

reduceReverse works great, but what if we want to reverse individual words while keeping the sentence order intact? This time, we split the string into an array of words and pass each word to our previously created reduceRerverse function.

Again, a reduceWordsBeginner exists which provides logging insight.

Reduce Map & Filter

You may have heard of map and filter, which are also available on the Array prototype. In general, I would recommend using them over reduce when applicable. However, since the goal is to learn, let’s prove reduce can map and filter.

In this example, we want to turn a list of people into heroes. For each person object, name is mapped to hero and age to yearsYoung.

people = [
 { name: ‘Brutus’, age: 48 },
 { name: ‘Remus’,  age: 26 },
 { name: ‘Pollux’, age: 33 },
 { name: ‘Nero’,   age: 17 }

Here, we’re only including a given number if even.

numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]

Yep. Reduce can do that too.

Reduce is a Higher-Order Function

To this point, we’ve defined reducer functionality through anonymous functions. However, reduce can receive a reducer as a variable. Consider the following:

This illustrates that reducer functionality can be predefined and used throughout an application as needed. Although we won’t explore it today, when used with currying this allows for some really cool functional programming.

Reduce, Reduce, Reduce

This merely scratches the surface of reduce use cases, but portrays the flexibility and power reduce offers. If you previously avoided reduce, hopefully this sparked a desire to add another tool to your Javascript belt.

Enjoy posts like these? Follow me on Twitter @andepaulj

Paul Anderson

Written by

Solutions engineer, music enthusiast, dog dad