Mastering the JavaScript Reduce method ✂️
Tags: javascript
Published: 2020-05-15 12:05:33

JavaScript roughly has 30 built-in methods for manipulating arrays. Chances are that you are probably using `map()`, `filter()` or e.g. `forEach()` quite often. But how often do you use the `reduce()` method? 

The reduce method is, in my opinion, **the most powerful array method of JavaScript**. For me it was unclear how this method exactly works for quite some time so in this article we will reveal the power of the reduce method! 😄

<hr>

# The basis

The reduce method always returns a **single value**, which is in contrast to map() and filter() which return a new array with one or more values.

It takes four arguments, but most of the time you'll only need the first two.
1. accumulator (often called `acc`)
2. current value (often called `cur`)
3. current index
4. source array

Let's say we have a list of scores and we want to display the sum of all scores. We could create a for-loop and count them in a new variable called `total`:
```javascript
const scores = [23,63,23,35];
let total = 0;
for (i = 0; i < scores.length; i++) {
  total += scores[i];
}
console.log(total); // 144
```

Reduce makes this much easier. We give it a **reducer function**, that applies some action on every item in the given array, and an **initial value** from where we want to start (in this case 0).

```javascript
const scores = [23,63,23,35];
const reducer = (acc, cur) => acc + cur;
const total = scores.reduce(reducer, 0);
console.log(total); // 144
```

We can refactor this to:

```javascript
const scores = [23,63,23,35];
const total = scores.reduce((acc, cur) => acc + cur, 0);
console.log(total); // 144
```

Awesome! Let's continue.

<hr>

# Flattening an array

Let's say we have an array with multiple arrays inside:

```javascript
let arrays = [[1, 2, 3], [4, 5], [6]];
```

and we want to convert this into one single array. How can we do this with reduce? We need to link together a.k.a. concatenate every array together, so we'll use `concat()` on every item and we'll set our initial value as an array:

```javascript
const flatten = arrays => arrays.reduce((acc, curr) => acc.concat(curr), []);
flatten(arrays); // [1, 2, 3, 4, 5, 6]
```

Yay! Let's do another one. 😃

<hr>

# Splitting values of two given arrays into two groups

Let's say we receive two arrays: one with a list of numbers and one with a list of true/false values and we want to filter the first list of numbers based on their true/false value.

```javascript
[1, 2, 3, 4], [true, true, false, true];
```

Another thing we can do easily with reduce! For our initial value, we'll set an array containing two empty arrays. We will apply the reduce method on the numbers array.

```javascript
const splitTrueFalse = (arr, filter) => arr.reduce((acc, cur) => ... ,[[],[]]);
```

Remember the reduce method takes a third argument, the index? We will use the index to determine if the values is true or false based on the second array.

We'll push the current number in the the first array if its value in the filter array is true by checking `filter[i] ? 1 : 0`. We'll return our `acc` array so we can keep push values to it.

```javascript
const splitTrueFalse = (arr, filter) => arr.reduce((acc, cur, i) => {
  acc[filter[i] ? 1 : 0].push(cur);
  return acc;
} ,[[],[]]);
```

We can refactor our code by returning `acc` in one line:

```javascript
 const splitTrueFalse = (arr, filter) => arr.reduce((acc, cur, i) => (acc[filter[i] ? 0 : 1].push(cur), acc), [[], []]);
```

Cool! Let's make it a bit more difficult. 😎

<hr>

# Creating an object from given key-value pairs.

In this example we'll receive an array containing multiple arrays, each with a key-value pair.

```javascript
const pairs = [['name', 'Sander'], ['age', 26], ['likes', 12]];
```

With reduce we can easily convert this to an object. First we'll set our initial value as an object, which we will fill it with every iteration.

```javascript
const arrToObject = arr => arr.reduce((acc, cur) => ... , {});
```

Next up we'll have to convert each array to a key-value pair inside our object.
The key we can get by grabbing the first value inside our array: `cur[0]` 
By using bracket notation we can set our key to a string value: `acc[cur[0]]`.

The value we'll get by grabbing the second item in the current array: `cur[1]`. 
As in the example before, we return our `acc` accumulated value every time so we can build upon our object.

```javascript
const arrToObject = arr => arr.reduce((acc, cur) => (acc[cur[0]] = cur[1], acc) , {});
```

Hope you have a better understanding of the awesome reduce method!

Make sure to follow me for more tips and tricks. 🧠