Understanding reduce in javascript
Tags: javascript, react, webdev
Published: 2021-07-29 17:43:08

Reduce is an array method that was introduced in javaScript in ES5 along with map and filter. Map and filter are pretty straightforward to understand but I had difficulty understanding reduce so in this blog we are going to understand reduce with the help of some examples.

As the name suggests reduce method is used to reduce the array to a single value.
According to MDN - 


> The reduce() method executes a reducer function (that you provide) on each element of the array, resulting in a single output value.

Now, this single output value could be anything, it could be a number, an object, or even an array.

Let's take an example - you have an array of numbers and you would want to calculate the sum of it.

```js
const arrayOfNumbers = [9,8,7,6,5];

```
so we can use reduce here as we want a single output, reduce method takes 2 parameters one is a callback function and the other is the initial value. The initial value is optional and if we don't provide it then it takes the first value of the array as an initial value and starts from 2nd value of an array.

```js
const sum = arrayOfNumbers.reduce(callbackFunction, initialValue)
```

If you don't provide the initial value there is a chance to get a type error if the array is empty, so it's a good practice to always include the initial value.

The callback function can have 4 arguments - 
- **accumulator** : it is the return value of the callbackFunction for the next iteration and for the first time it is initialValue. 
- **currentValue** : the current array item
- **index** : index of the currentValue
- **wholeArray** : the complete array on which we are applying reduce

```js
const callbackFunction = (accumulator, currentValue, index, wholeArray) => {
// doSomethingHere
}
```

index and wholeArray arguments are optional and can be omitted. In 99% of cases, only the first two arguments are needed

In this example, while looping through the array in each iteration we add the currentValue to the accumulator and return it this return becomes the accumulator for the next iteration.

```js
const callbackFunction = (accumulator, currentValue) => {
    return accumulator + currentValue;
}
```

We can write this in one line using arrow function as well - 
```js
const arrayOfNumbers = [9,8,7,6,5]
const sum = arrayOfNumbers.reduce((accumulator,currentValue) => accumulator + currentValue, 0)
```

This would have ran the loop 5 times - 

**Iteration number ---> accumulator ---> currentValue**

1 --->0(initialValue) ---> 9

2 ---> 9(0 + 9) ---> 8

3 --->17(9 + 8) ---> 7

4 --->24(17 + 7) ---> 6

5 --->30(24 + 5) ---> 5

and then it returns 35


This was a straightforward example now lets take a complex example.
We are given an array of students data and we need to group students with their favourite fruit.

```js
const studentsData = [
{
     name: 'Shaurya',
     favouriteFood: 'Mango'
},
{
     name: 'Priya',
     favouriteFood: 'Apple'
},
{
     name: 'Rishabh',
     favouriteFood: 'Mango'
},
{
     name: 'Shubham',
     favouriteFood: 'Grapes'
},
{
     name: 'Ashish',
     favouriteFood: 'Strawberry'
},
]
```

Now we need to return an object with fruits as keys and students as array values.
So we take initialValue as an empty object and will iterate through the array and check for each student if fruit is present in accumulator then push the student to its array else add the fruit as key and push the student as its value in array.

```js
const groupByFavouriteFruits = studentsData.reduce((accumulator, currentStudent) => {
    let key = currentStudent.favouriteFood;
    let name = currentStudent.name;

    if( !accumulator[key] ){
        accumulator[key] = [];   
    }
    accumulator[key].push(name);
},
{})

//  so groupByFavouriteFruits becomes 
// {
//     Mango : [ 'Shaurya', 'Rishbah' ],
//     Apple : [ 'Priya' ],
//     Grapes : [ 'Shubham' ],
//     Strawberry : [ 'Ashish' ]
// }
```

Reduce is a very powerful array method, although it is a bit harder a understand but it has various use cases. The Map and Filter Array methods can also be written through Reduce but that will be a topic for another blog.

If you want to read more about reduce MDN has a very detailed doc on it - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce


Quirky tip - There is a reduceRight method as well, which works same as reduce but the array is traversed right to left.