What is .reduce()?

.reduce() is a method that lets you turn an array into a single value — like a number, object, array, or string.

It does this by going through every item in the array one by one, and combining them using a reducer function.

Imagine this:

You have a bunch of space toys, and you want to pack them into one box.
But instead of just throwing them in, you carefully choose how they go together. That's what .reduce() does.


Syntax

array.reduce<ReturnType>(
  (accumulator, currentValue, currentIndex, array) => {
    // logic here...
    return newAccumulator;
  },
  initialValue // where the result starts from
);
  • accumulator: the result you're building
  • currentValue: current item from the array
  • initialValue: starting point of the result

✨ Example 1: Add Numbers

const numbers = [10, 20, 30];

// // let acc = $1 // (only for explanation, not needed in actual code)

// Step 1: acc = 0 + 10 → 10
// Step 2: acc = 10 + 20 → 30
// Step 3: acc = 30 + 30 → 60

const total = numbers.reduce((acc, curr) => acc + curr, 0);
console.log(total); // 60

✨ Example 2: Count Emojis

const fruits = ["🍎", "🍌", "🍎"];

// let acc = $1 // (only for explanation, not needed in actual code) // start as empty object

// Step 1: "🍎" → acc = { "🍎": 1 }
// Step 2: "🍌" → acc = { "🍎": 1, "🍌": 1 }
// Step 3: "🍎" again → acc = { "🍎": 2, "🍌": 1 }

const count = fruits.reduce((acc, fruit) => {
  acc[fruit] = (acc[fruit] || 0) + 1;
  return acc;
}, {});

console.log(count); // { "🍎": 2, "🍌": 1 }

✨ Example 3: Flatten Arrays

const nested = [[1, 2], [3, 4], [5, 6]];

// let acc = $1 // (only for explanation, not needed in actual code)

// Step 1: acc = [1, 2]
// Step 2: acc = [1, 2, 3, 4]
// Step 3: acc = [1, 2, 3, 4, 5, 6]

const flat = nested.reduce((acc, curr) => acc.concat(curr), []);
console.log(flat); // [1, 2, 3, 4, 5, 6]

Real Project Example

In a real project, I used .reduce() to combine multiple rows from a database into a single user object, and gather all their unique permissions into one set.

// ...
const user = result.reduce((acc, curr) => {
  if (!acc.id) return {
    ...curr,
    permissions: new Set(curr.permissions)
  };

  if (!curr.permissions) return acc;

  for (const p of curr.permissions) {
    acc.permissions.add(p);
  }

  return acc;
}, {} as Omit<typeof result[number], 'permissions'> & { permissions: Set<string> });

const finalUser = {
  ...user,
  permissions: Array.from(user.permissions),
};

console.log(finalUser)

  /**
    {
    "id": ""68215898-44ba-4836-8b23-9a2e9809a04d"",
    "email": "test3@test.com",
    "name": "Test User 3",
    "applicationId": "bba755bc-a300-4b93-9a5b-0bfd6465fe80",
    "roleId": "3297103d-ce30-447b-9161-9c7d7be835a5",
    "password": "$argon2id$v=19$m=65536,t=3,p=4$EXtKvVlvjMqV56smKkwiZg$BycibZhiZRpOLwbY79X/amwUDkSZ/mErNALoCTGeUiw",
    "permissions": [
      "posts:write",
      "posts:read"
    ],
    "createdAt": "2025-05-20T12:13:18.429Z"
  }
   */

In this example:

  • The result array contains rows for the same user (from a SQL JOIN).
  • We use .reduce() to merge them into one object.
  • The Set ensures the final permissions list has no duplicates.

This is where .reduce() really shines: combining structured data into a new shape.


✅ Best Practices

  • Always provide an initialValue.
  • Keep your reducer pure — don't change outside variables.
  • Use **.reduce()** only when you want a single result.

❌ When Not to Use .reduce()

Use simpler methods like .map(), .filter(), or for...of if:

  • You don't need a single value.
  • Your logic is very complex.

🧑‍🚀 Recap

  • .reduce() loops through your array and builds a result.
  • You control how it combines items.
  • It’s useful for totals, counts, grouping, or transforming.
  • Use it only when it makes your code clearer, not more confusing.

You now understand .reduce() like a true code astronaut 🚀

Arshia Shahidi | Understanding .reduce() in JavaScript (Step-by-Step)