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 buildingcurrentValue
: current item from the arrayinitialValue
: 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 finalpermissions
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 🚀