What is Array.reduce() and how to use it?

What is Array.reduce() and how to use it?

What is reduce method?

If you have used functional programming, then you might have come across reduce method a lot of times. reduce is one of the methods that follow the functional programming paradigm:

  1. it is predictable, we get the same output for the same input

  2. it does not mutate the original input and returns us a new value.

As per MDN:

The reduce() method is an iterative method. It runs a "reducer" callback function over all elements in the array, in ascending-index order, and accumulates them into a single value. Every time, the return value of callbackFn is passed into callbackFn again on next invocation as accumulator. The final value of accumulator (which is the value returned from callbackFn on the final iteration of the array) becomes the return value of reduce().

Here is another analogy to understand reduce() implementation:

Suppose a group of workers are given raw materials and are asked to build a wall. each worker will work his part and the next worker will continue working from where the previous worker left. This process repeats for every worker till the wall is completely built. This is exactly how reduce operates.

The raw material is our input array that reduces operates on, the workers are the callback functions that are executed on each iteration, the final complete wall is the value of the accumulator that reduce method will return eventually and the current state of the wall after every person completes his work is the current value of accumulator after each iteration.

reduce method syntax

the syntax of reduce method is like this:

reduce((accumulator, currentValue, currentIndex, array) => { }, initialValue)

reduce accepts a callback function as an argument and an initial value(optional). This callback contains an accumulator value which will be returned after all iterations are completed and the current value. We can also provide the current index and the original array as callback function arguments.

key points for using reduce method

there are a few gotchas for using reduce method:

  1. if we do not give any initial value for the accumulator then the first item of the array will be the initial value of the accumulator and the array will iterate from the second item of the array.
const arr = [1,2,3,4,5]
//below we are not providing intial value for accumulator
//so initial value will be set to arr[0] and iteration will start from arr[1]
const totalSum = arr.reduce((acc, cur) => acc + cur)
console.log(totalSum)// output: 15
  1. the callback function that will be called for each iteration will return the current value of the accumulator and that will be used in the next iteration.

  1. for the callback function inside the reduce we need to make sure to use the return keyword if we are not specifying a single-line arrow function

const arr = ["i", "am","jay"]
//in below callback function, since we have not given the return keyword, the acc value will be "undefined" after the first iteration.
// that that will not give us the expected output.
const joinString = arr.reduce((acc, cur) => {
  //this will print present value for acc and cur for each iteration
  console.log( "acc: " + acc + ", " + "cur: "+cur)
   acc + cur + " " //callback not returning any value
},"Hi! ")
console.log(joinString)// expected output: 'Hi! i am jay'

use cases of reduce

reduce is like a swiss knife that can be used in a variety of ways. Here is an accurate meme shared by Chirag Taluja on the discord server of the coding boot camp that I am attending.

transforming an array

reduce can be used to create a new array by applying some transformation just like map()

const arr = [1,2,3,4,5] 
//we are using reduce to create a new array with elements that are square of each item from original array
const arrSquare = arr.reduce((acc, cur) => [...acc, cur * cur], [])
arrSquare //[ 1, 4, 9, 16, 25 ]

filtering an array

we can use reduce to filter out items from an array and create a new array of filtered items

const arr = [1,2,3,4,5] 
//we are using reduce to filter out only even numbers from original array
const arrSquare = arr.reduce((acc, cur) => cur % 2 === 0 ? [...acc, cur]: acc, [])
arrSquare //[2,4]

counting items

reduce() can be used to count the number of occurrences of array items.

const fruits = ['orange','apple','mango', 'apple', 'apple', 'mango', 'banana'] 
//we are using reduce to count the number of fruits and store it in an object
const countFruits = fruits.reduce((acc, cur) =>{
  if(acc[cur]){
   return {...acc, [cur]: acc[cur] + 1}
  }else{
   return {...acc, [cur]:1}
  }
}, {})
countFruits // output : { orange: 1, apple: 3, mango: 2, banana: 1 }

finding an item

we can also use reduce to find any item from an array that matches our condition.

const arr = [{name:'rahul', age:28}, {name:'suraj', age:21}, {name:'kiran', age:24}, {name:'ashish', age:32}] 
//we are using reduce to find the oldest person
//we set the initial value of acc to first item of the array
const oldestPerson = arr.reduce((acc, cur) =>{
  return acc.age < cur.age ? cur : acc
}, arr[0]).name
console.log(oldestPerson) // outoput : 'ashish'

conclusion

As we saw above, reduce() is a beast and can be used in a variety of ways. To summarize:

reduce is an array method that iterates over the array using a callback function, sets an accumulator value initially before the iteration starts and updates that value on each callback iteration. after we iterate over all the items, this accumulator value is returned

Thank you for reading!

Further reading:
MDN reduce