JavaScript reduce Method
Table of Contents + −
In the previous lesson, we learned how to pull a single matching item out of an array. Now let’s learn how to boil an entire array down to one value with the reduce method.
🪄 What is the reduce Method?
The reduce method takes every item in an array and combines them into a single result. That result can be a number, a string, an object, or anything else you build up along the way.
You give reduce a callback function. That callback receives two main values: the accumulator and the current item. The accumulator is the running result that carries over from one item to the next. The current item is the array element being looked at right now.
const numbers = [1, 2, 3, 4];
const total = numbers.reduce((accumulator, current) => { return accumulator + current;}, 0);
console.log(total); // 10Let’s walk through what each line does:
const numbers = [1, 2, 3, 4]is the array we want to combine into one number.numbers.reduce((accumulator, current) => { ... }, 0)callsreducewith a callback and the starting value0.accumulatoris the running result so far;currentis the array item being looked at right now.return accumulator + currentadds the current item to the running result and hands it back as the new accumulator.- The
0after the callback is the starting value of the accumulator. Whatever the callback returns becomes the accumulator for the next item, so after all four itemstotalis10.
🔢 A Simple Example: Summing an Array
Adding up a list of numbers is the classic use of reduce. The accumulator starts at 0 and grows by each number in turn.
const scores = [10, 20, 30];
const sum = scores.reduce((total, score) => total + score, 0);
console.log(sum); // 60Let’s trace this line by line:
const scores = [10, 20, 30]is the array of numbers we want to add up.scores.reduce((total, score) => total + score, 0)runs the callback once for each score, starting the accumulator at0.totalis the accumulator (the running sum);scoreis the current number.total + scoreis returned each time, becoming the new running sum for the next item.- On the first run,
totalis0(the initial value) andscoreis10, so the callback returns10. That10becomes the newtotalfor the next item.
The table below traces every step.
| Step | Accumulator (before) | Current item | Returned (new accumulator) |
| 1 | 0 | 10 | 10 |
| 2 | 10 | 20 | 30 |
| 3 | 30 | 30 | 60 |
The accumulator carries the running total across every iteration. After the last item, reduce hands back the final accumulator, which is 60.
The accumulator is the memory
Think of the accumulator as the method’s memory. It holds the result so far, and each iteration updates it. The value you return is the value the next iteration receives.
🛒 A Practical Example: Total Price of a Cart
reduce shines when an array holds objects. Here a shopping cart holds items, and we add up the price of each one to get an order total.
const cart = [ { name: "Notebook", price: 5 }, { name: "Pen", price: 2 }, { name: "Backpack", price: 40 },];
const total = cart.reduce((sum, item) => sum + item.price, 0);
console.log(total); // 47Let’s break this down step by step:
cartis an array of objects, each with anameand aprice.cart.reduce((sum, item) => sum + item.price, 0)runs the callback once per item, starting the accumulator at0.sumis the accumulator (the running total);itemis the current cart object.sum + item.pricereads the price off the current item and adds it to the running total, returning that as the new accumulator.- After the last item, the accumulator holds
5 + 2 + 40, sototalis47.
You can also build something other than a number. Here reduce builds a single object that counts how many of each fruit appears.
const fruits = ["apple", "banana", "apple", "cherry", "banana", "apple"];
const counts = fruits.reduce((tally, fruit) => { tally[fruit] = (tally[fruit] || 0) + 1; return tally;}, {});
console.log(counts); // { apple: 3, banana: 2, cherry: 1 }Let’s see how the accumulator grows here:
fruitsis the array of fruit names, with some repeats we want to count.- The initial value is an empty object
{}, so the accumulatortallystarts as an empty object instead of a number. tallyis the running object of counts;fruitis the current fruit name.tally[fruit] = (tally[fruit] || 0) + 1looks up the current count for that fruit (using0if it isn’t there yet) and adds one.return tallyhands the same object back so the next iteration keeps building on it. After every fruit,countsholds the full tally.
⚠️ Common Mistakes to Avoid
| Mistake | Problem | Solution |
| Forgetting the initial value | The first item becomes the accumulator, which breaks object or string results and throws on an empty array | Always pass a starting value, like 0 or {}, as the second argument |
| Not returning the accumulator | The accumulator becomes undefined on the next iteration | Always return the accumulator from the callback |
| Using reduce when map or filter is clearer | The code is harder to read than it needs to be | Reach for map to transform and filter to select; use reduce only to combine into one value |
Here is the difference between forgetting and returning the accumulator:
const numbers = [1, 2, 3];
// ❌ The callback returns nothing, so the accumulator becomes undefinednumbers.reduce((acc, n) => { acc + n;}, 0);
// ✅ The callback returns the accumulator every timenumbers.reduce((acc, n) => { return acc + n;}, 0);Let’s compare the two calls:
- In the first call,
acc + nis computed but never returned, so the callback hands backundefined. On the next iterationaccisundefined, and the math falls apart. - In the second call,
return acc + npasses the new running total back, soacccarries the correct sum into every iteration. - The only difference is the
returnkeyword, and it is the difference between a working sum and a broken one.
When not to use reduce
If you only want to change each item, use map. If you only want to keep some
items, use filter. Save reduce for when you truly need to fold the whole
array into a single value.
🔧 Try It Yourself!
- Create an array of numbers and use
reduceto add them all together. Start the accumulator at0. - Trace each step on paper: write the accumulator before and after every item.
- Create an array of objects with a
pricefield and usereduceto find the total price. - Remove the initial value from your sum and watch what happens with an empty array.
- Use
reduceto find the largest number in an array by keeping the bigger value each step.
🧩 What You’ve Learned
- ✅
reduceboils an array down to a single value - ✅ The callback receives the accumulator and the current item
- ✅ The accumulator is the running result that carries across iterations
- ✅ The second argument is the starting value of the accumulator
- ✅ Always return the accumulator from the callback
- ✅ Use
maporfilterwhenreducewould be overkill
🚀 What’s Next?
Now that you can combine an array into one value, let’s learn how to check whether at least one item passes a test. Let’s continue to some.