Skip to content

reduce

reduce is the most flexible array method. Where map always returns an array of the same length and filter always returns a subset, reduce can return anything: a number, a string, an object, or a new array. Its job is to collapse an entire array into a single accumulated value.

reduce takes two arguments: a reducer function and an initial value.

The reducer function is called once for each item. It receives:

  1. The accumulator — the running result, starting at the initial value
  2. The current item
  3. (Optionally) the current index and the original array

Whatever the reducer returns becomes the new accumulator for the next call. After the last item, the final accumulator value is returned.

const expenses = [
{ id: 1, description: 'Coffee', amount: 4.50, category: 'Food' },
{ id: 2, description: 'Bus pass', amount: 30.00, category: 'Transport' },
{ id: 3, description: 'Lunch', amount: 12.75, category: 'Food' },
{ id: 4, description: 'Gym membership', amount: 45.00, category: 'Health' },
{ id: 5, description: 'Dinner out', amount: 38.20, category: 'Food' },
];
const total = expenses.reduce((acc, expense) => acc + expense.amount, 0);
console.log(total); // 130.45

Walk through the first two iterations:

  • Start: acc = 0
  • Item 1 (Coffee): 0 + 4.50 = 4.50 → new acc
  • Item 2 (Bus pass): 4.50 + 30.00 = 34.50 → new acc
  • …and so on until all five items have been processed

You can technically omit the initial value — reduce will use the first array item as the starting accumulator. Do not do this. It makes the code harder to read and breaks on empty arrays. Always pass an explicit initial value as the second argument.

// ✓ explicit initial value
const total = expenses.reduce((acc, e) => acc + e.amount, 0);
// ✗ omitted — fragile on empty arrays, less readable
const total = expenses.reduce((acc, e) => acc + e.amount);

The total-amount pattern is the most common reduce use case in BudgetBuddy:

function getTotal(expenses) {
return expenses.reduce((acc, e) => acc + e.amount, 0);
}
console.log(getTotal(expenses).toFixed(2)); // '130.45'

reduce can build objects as the accumulator. This is how you produce a count or sum grouped by category:

const byCategory = expenses.reduce((acc, expense) => {
const key = expense.category;
acc[key] = (acc[key] || 0) + expense.amount;
return acc;
}, {});
console.log(byCategory);
// { Food: 55.45, Transport: 30, Health: 45 }

Step by step for the Food category:

  • First Food item (Coffee, $4.50): acc['Food'] is undefined0 + 4.50 = 4.50
  • Second Food item (Lunch, $12.75): 4.50 + 12.75 = 17.25
  • Third Food item (Dinner out, $38.20): 17.25 + 38.20 = 55.45

The acc[key] || 0 pattern handles the first time a key appears — undefined || 0 is 0.

Another common pattern: convert an array to an object keyed by ID for fast lookup:

const expenseMap = expenses.reduce((acc, expense) => {
acc[expense.id] = expense;
return acc;
}, {});
console.log(expenseMap[3]);
// { id: 3, description: 'Lunch', amount: 12.75, category: 'Food' }

This lets you look up any expense by ID in O(1) time rather than scanning the array with find every time.

reduce is powerful, but it is also the easiest method to misuse. Use it when:

  • You are summing or aggregating values
  • You are grouping items into an object
  • You need to collapse an array into any non-array result

Do not use reduce when map or filter would be clearer — those names communicate intent; reduce only communicates “this collapses somehow.”

Using the expenses array from this lesson:

  1. Use reduce to calculate the total of all amount values.
  2. Use reduce to calculate the total for the 'Food' category only. (You can filter first, or handle it inside the reducer.)
  3. Use reduce to build an object like { Food: 3, Transport: 1, Health: 1 } — a count of expenses per category (not sum, count).
  4. Use reduce to build an object keyed by id where each value is the full expense object.
  • reduce collapses an array into a single accumulated value — a number, string, object, or anything else.
  • The reducer receives the accumulator and the current item; return the new accumulator each time.
  • Always provide an explicit initial value as the second argument.
  • Use it for sums, aggregations, groupings, and building lookup objects.
  • Prefer map or filter when they fit — use reduce when neither does.