A few months ago, I wrote this blog post on the wonders of the JavaScript .reduce() method. In that post, I celebrated my newfound love for the powerful method I once avoided.
But last week, I stumbled on a video by the Chrome Developers YouTube channel (link below) that challenged my stance on .reduce()
.
Is reduce() bad?
No! In my humble opinion, it was clearly the greatest thing since sliced bread. Not only can you use .reduce()
to well...reduce, but you can use it to map and filter. You can use .reduce()
to keep tall, to cross-reference multiple arrays, to flatten arrays and more!
How could reduce()
possibly be bad?
Well, as the old adage reminds us– just because you can, it doesn't mean you should. So I watched the video. And 2 minutes in, I understood the point of the video's initial questions.
While .reduce()
is a very powerful method, it's not always the easiest to read or grasp at a glance. In fact, reviewing some of my most efficient .reduce()
functions, it took me a bit to unravel some of the logic.
As Jake explained in the video, 'the simplest code is written sequentially'.But the reduce method is ordered in a funky, nonchronological way. The syntax for .reduce()
is:
array.reduce((accumulator, currentValue, currentIndex, array), initialValue)
To understand how the method below is executing, you would need to start at the end for the initial value, then take one step back into the function for the operators and then look at the accumulator to anticipate the result.
const reduce = (arr) => {
return arr.reduce((accumulator, currentValue, currentIndex, array) => {
return accumulator + currentValue
}, 10)
}
reduce([10,23,5]) // result = 48
When should you .reduce()
?
You should be using reduce for actual reductions, meaning you have an array that you want to reduce to one value. This should be the value held in your accumulator.
When should you not use .reduce()
?
If you're not sure how to differentiate between when .reduce()
is or is not appropriate, ask yourself-- can the behavior you're trying to execute be achieved by instead using:
- map
- filter
- loop
It could be that .reduce()
is the more elegant solution for a particular task. In those instances, also ask yourself-- does reduce make my code more or less readable?
Discuss:
You're given three arrays and asked to return the numbers found in all three arrays. Looking at the code snippet below, would you use .reduce()
or is there a better solution?
let arr1 = [8,5, 12,90,65,1,0,768,8,4]
let arr2 = [34,3,0,45,23,67,1,5, 15, 67,09]
let arr3 = [10,23,5]
const intersection = (input) => {
return input.reduce((acc, arr) => {
return acc.filter(num => arr.indexOf(num)!==-1)
})
}
console.log(intersection([arr1, arr2, arr3])) // result = [5]
Check out the Chrome developers video I mentioned earlier.
Also, take a look at this blog post by the Khan Academy engineering team. Josh Comeau offers some great examples of how to use .reduce()
.