Why do I need to use reduce method in Javascript
Nikolas โก๏ธ
Posted on March 25, 2023
Also available on my blog
I don't use reduce method and I'm good with it
Probably you already are a pretty experienced Javascript developer but you have not used .reduce()
method in your
production code yet'. You still can't find the right use case for this method.
What does it do and why do I want to use it? - you may ask.
In this article I'll show you many code examples where .reduce()
is a great choice.
Basics
When you need to iterate over an array you can use for
, forEach
or for..of
. When you need to iterate and return
data (most of the time - modified) data for each element you probably would use map
.
reduce
is a little different comparing to the methods listed above. It is used to calculate a single value based
on the array.
Here is a little example showing the main differences:
map([๐ฝ, ๐ฎ, ๐], cook) => [๐ฟ, ๐, ๐ณ]
filter([๐ฟ, ๐, ๐ณ], isVegetarian) => [๐ฟ, ๐ณ]
reduce([๐ฟ, ๐ณ], eat) => ๐ฉ
I hope you already get the basics, right?
Basic use case
The best example that meets our assumptions of calculating a single value based on the array is getting the total of some order.
Below you can see the array of products with its prices. The easiest way to calculate the order's total would be using
for..of
:
const order = [
{ product: '๐', price: 21 },
{ product: '๐', price: 37 },
{ product: '๐ฆบ', price: 69 },
];
let total = 0; // 127
for (const item of order) {
total += item.price
}
reduce
solves the same problem in a convenient one-liner:
const total = order.reduce((total, item) => total + item.price, 0) // 127
Plenty of extra examples
In this section I'll show you many other examples of using reduce
. Please keep in mind that many of these can, and
should be, rewritten using more appropriate and more efficient array methods.
Let's start with the list of ingredients for a scrambled eggs ๐ณ:
const ingredients = [
{id: 1, name: "egg ๐ฅ", calories: 140, diet: "vegetarian"},
{id: 2, name: "egg ๐ฅ", calories: 140, diet: "vegetarian"},
{id: 3, name: "butter ๐ง", calories: 90, diet: "vegetarian"},
{id: 4, name: "bacon ๐ฅ", calories: 210, diet: "carnivore"}
]
Count ingredients
result = ingredients.reduce((acc, item) => acc + 1, 0); // 4
// alternative way
result = ingredient.lenght; // 4
Sum calories of all ingredients
result = ingredients.reduce((acc, item) => acc += item.calories, 0) // 580
// alternative way
// .reduce is problably the best solution in this case
Array of ingredients names
result = ingredients.reduce((acc, item) => [...acc, item.name], []) // [ 'eggs', 'butter', 'bacon' ]
// alternative way
result = ingredients.map(item => item.name); // [ 'eggs', 'butter', 'bacon' ]
Count occurrences
result = ingredients.reduces((acc, item) => {
return {...acc, [person.age]: (acc[person.age] ||0) + 1} // { 'egg ๐ฅ': 2, 'butter ๐ง': 1, 'bacon ๐ฅ': 1 }
}, {})
// alternative way
// using lodash
_.countBy(ingredients, "name");
Group by diet type
result = ingredients.reduce((grouped, item) => {
const {diet, name} = item;
if(grouped[diet] == null) grouped[diet] = [];
grouped[diet].push(name)
return grouped
}, {}) // {vegetarian: [ 'egg ๐ฅ', 'egg ๐ฅ', 'butter ๐ง' ], carnivore: [ 'bacon ๐ฅ' ]}
// alternative way (need to be transformed to return just names)
_.groupBy(ingredients, "diet");
Ingredients lookup by ids
result = ingredients.reduce((acc, item) => {
return {...acc, [item.id]: item}
}, {})
/*
{
'1': {
id: 1,
name: 'egg ๐ฅ',
calories: 140,
diet: 'vegetarian'
},
'2': {
id: 2,
name: 'egg ๐ฅ',
...
*/
Creating such object gives us an efficiency advantage when we want to access one specific element - we don't have to
iterate over a whole array looking for matching element.
Get the ingredient with the most calories
result = ingredients.reduce((acc, item) => {
if (acc === null || item.calories > acc) return item.calories
return acc
}, null) // 210
// alternative way
result = Math.max(...ingredients.map(item => item.calories)) // 210
Summary
After reading and understanding all of these examples I'm sure that you know in which cases reduce
would be the best solution.
Using reduce
seems to be a great way to solve some problems in Javascript but at the same time there is also opposite
perspective among many developers. Jake Archibald (@jaffathecake) posted a tweet about this:
All code using array.reduce should be rewritten without array.reduce so it's readable by humans mutes thread
Now it is only your responsibility to decide whether you want to incorporate reduce
method to your everyday life or
maybe you want to stick to Jake's perspective and use other array methods combined with widely known lodash for example.
Posted on March 25, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.