# Functional Basics #3: Reduce

Welcome back! In the third part of this mini-series on functional programming basics, I'll be taking a more in-depth look at a slightly more complex array function -`reduce`.

If you haven't already read it, I recommend starting with the first article in this series, Functional Basics #1: Map. I'll be building on some ideas as the series progresses.

### What is it?

Let's recap on the array functions we've looked at so far:

• `map` runs a function on each element of an array, and returns an array of the results.
• `filter` checks each element of an array by running a predicate function on it, and returns an array with only the elements for which the predicate returns `true`.

So what's `reduce`? Well, like the name suggests:

• `reduce` runs a function on each element of an array, and reduces the array to a single value.

Cue a simple example - we have an array of numbers, and we want to add the square of each number to get a total. Before we look at how `reduce` could do this, let's just implement it ourselves, in imperative style, with a `for` loop:

``````const myArray = [2, 9, 34, 22]
let total = 0

for (let i = 0; i < myArray.length; i++) {
const num = myArray[i]
const square = num * num
total += square
}

// total: 1725

``````

If you've been following this series, you know the drill here - let's refactor the calculation out of the for loop:

``````const myArray = [2, 9, 34, 22]
let total = 0

const addSquare = (total, num) => total + num * num

for (let i = 0; i < myArray.length; i++) {
const num = myArray[i]
}

// total: 1725

``````

The `addSquare` function which we've extracted here is known as a reducer function. It takes the current total and the next number in the array, and returns the new total. This means that if we apply this function to every number in the array, passing in the running total each time, we'll eventually reduce the array down to a single value - the final total.

Here's how that looks using `reduce`:

``````const myArray = [2, 9, 34, 22]

const addSquare = (total, num) => total + num * num

// total: 1725
``````

So much cleaner! There's a couple of things to note here:

• The first argument to reduce is our reducer function, `addSquare`.
• The second argument (`0` in this case) is the initial value of `total`. This is equivalent to where we had previously used `let total = 0`.

Getting the right initial value is important! If we miss it out, Javascript will take the first element in the array as the initial value instead of running our reducer on it, and we'll get the wrong result:

``````const myArray = [2, 9, 34, 22]

const addSquare = (total, num) => total + num * num

// total: 1723 - wrong!
``````

A brief interlude for some terminology:

• The `total` value, the first argument to a reducer function, is more generally known as the accumulator - it 'accumulates' the result of running the reducer on each array element. Commonly shortened to `acc`.
• `num` here is referred to as the current element, shortened to `cur`.

Important to note that a reducer should always return the value which will be the `acc` for the next iteration. Therefore, the definition for ALL reducer functions should look like:

``````(acc, cur) => {
// do stuff here
return nextAccValue
}
``````

### What else can `reduce` do?

It can build anything! You can use it to generate any value - a number, a string, an object, even another array (because an array itself is a value). Here's an example to categorise words into an object by their length:

``````const words = ['the', 'quick', 'brown', 'fox', 'jumped', 'over', 'the', 'lazy', 'dog']

const result = words.reduce((acc, cur) => {
// If the key for this word length doesn't exist yet, make it an empty array
if (!acc[cur.length]) {
acc[cur.length] = []
}
// Add the current word to the right key for its length
acc[cur.length].push(cur)
return acc
}, {})

/* result:
{
'3': [ 'the', 'fox', 'the', 'dog' ],
'4': [ 'over', 'lazy' ],
'5': [ 'quick', 'brown' ],
'6': [ 'jumped' ]
}
*/
``````

Note how this time the reducer function is passed directly to `reduce` as an anonymous function - this is common. Also note that the initial value is an empty object, `{}`. The reducer takes this empty object and builds the result by adding keys and values as it goes.

Another handy use of reduce is to avoid having to iterate over an array more times than necessary. Assume we have an array of numbers which we want to:

• multiply by 4
• then filter to only include numbers greater than 20
• then sum the total

We could do it like this:

``````const nums = [1, 2, 3, 4, 5, 6, 7, 8, 9]

const times4 = num => num * 4
const greaterThan20 = num => num > 20
const sum = (acc, cur) => acc + cur

const result = nums
.map(times4)
.filter(greaterThan20)
.reduce(sum, 0)

// result: 120
``````

This looks nice and clean gives the right result, but has a problem - it loops over the array three times, once each for `map`, `filter` and `reduce`. This could have a noticeable impact on the performance of our code if we're processing very large arrays. Instead, we can refactor the `map`, `filter` and `reduce` into a single reducer which does everything required in one loop of the array:

``````const nums = [1, 2, 3, 4, 5, 6, 7, 8, 9]

const result = nums.reduce((acc, cur) => {
// Multiply by 4
const product = cur * 4
// If not greater than 20, filter this number out by returning the acc unchanged
if (!(product > 20)) {
return acc
}
// Otherwise return the sum of the acc and the product
return acc + product
}, 0)

// result: 120
``````

From this we can begin to see how flexible and powerful `reduce` can be. Since we have replaced a `map` and a `filter` operation with a single reducer, it's apparent that we could actually write our own version of the `map` and `filter` functions using only `reduce` (if you're up for the challenge, give it a go and post your solution in the comments!)

Hope this has been helpful, stay tuned for more articles on functional programming soon!