DEV Community

Cover image for Understanding reduce in javascript
Shaurya Vardhan Singh
Shaurya Vardhan Singh

Posted on

Understanding reduce in javascript

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.

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

Enter fullscreen mode Exit fullscreen mode

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.

const sum = arrayOfNumbers.reduce(callbackFunction, initialValue)
Enter fullscreen mode Exit fullscreen mode

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
const callbackFunction = (accumulator, currentValue, index, wholeArray) => {
// doSomethingHere
}
Enter fullscreen mode Exit fullscreen mode

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.

const callbackFunction = (accumulator, currentValue) => {
    return accumulator + currentValue;
}
Enter fullscreen mode Exit fullscreen mode

We can write this in one line using arrow function as well -

const arrayOfNumbers = [9,8,7,6,5]
const sum = arrayOfNumbers.reduce((accumulator,currentValue) => accumulator + currentValue, 0)
Enter fullscreen mode Exit fullscreen mode

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.

const studentsData = [
{
     name: 'Shaurya',
     favouriteFood: 'Mango'
},
{
     name: 'Priya',
     favouriteFood: 'Apple'
},
{
     name: 'Rishabh',
     favouriteFood: 'Mango'
},
{
     name: 'Shubham',
     favouriteFood: 'Grapes'
},
{
     name: 'Ashish',
     favouriteFood: 'Strawberry'
},
]
Enter fullscreen mode Exit fullscreen mode

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.

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' ]
// }
Enter fullscreen mode Exit fullscreen mode

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.

Top comments (2)

Collapse
 
jonrandy profile image
Jon Randy πŸŽ–οΈ • Edited

Reduce is really useful. "Write a function to convert a binary number into decimal without using parseInt" - OK...

const binToDec = str => [...str].reduce((a,v)=>+v+a*2,0)

console.log(binToDec('11101')) // 29
Enter fullscreen mode Exit fullscreen mode
Collapse
 
wulforr profile image
Shaurya Vardhan Singh

Thats really awesome Jon. Using reduce in this way never crossed my mind, this really opens up many possibilities