skip to content
Nikolas Barwicki - Javascript Blog Nikolas's Blog

SEO in Next.js 13 with Metadata API

/ 4 min read

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.