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.
The mechanics
Section titled “The mechanics”reduce takes two arguments: a reducer function and an initial value.
The reducer function is called once for each item. It receives:
- The accumulator — the running result, starting at the initial value
- The current item
- (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.45Walk 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
Always provide the initial value
Section titled “Always provide the initial value”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 valueconst total = expenses.reduce((acc, e) => acc + e.amount, 0);
// ✗ omitted — fragile on empty arrays, less readableconst total = expenses.reduce((acc, e) => acc + e.amount);Summing a property
Section titled “Summing a property”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'Counting items per category
Section titled “Counting items per category”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']isundefined→0 + 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.
Building a lookup object (id → expense)
Section titled “Building a lookup object (id → expense)”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.
When to reach for reduce
Section titled “When to reach for reduce”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.”
Exercise
Section titled “Exercise”Using the expenses array from this lesson:
- Use
reduceto calculate the total of allamountvalues. - Use
reduceto calculate the total for the'Food'category only. (You can filter first, or handle it inside the reducer.) - Use
reduceto build an object like{ Food: 3, Transport: 1, Health: 1 }— a count of expenses per category (not sum, count). - Use
reduceto build an object keyed byidwhere each value is the full expense object.
reducecollapses 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
maporfilterwhen they fit — usereducewhen neither does.