JavaScript reduce Method

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.

reduce.js
const numbers = [1, 2, 3, 4];
const total = numbers.reduce((accumulator, current) => {
return accumulator + current;
}, 0);
console.log(total); // 10

Let’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) calls reduce with a callback and the starting value 0.
  • accumulator is the running result so far; current is the array item being looked at right now.
  • return accumulator + current adds the current item to the running result and hands it back as the new accumulator.
  • The 0 after the callback is the starting value of the accumulator. Whatever the callback returns becomes the accumulator for the next item, so after all four items total is 10.

🔢 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.

reduce.js
const scores = [10, 20, 30];
const sum = scores.reduce((total, score) => total + score, 0);
console.log(sum); // 60

Let’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 at 0.
  • total is the accumulator (the running sum); score is the current number.
  • total + score is returned each time, becoming the new running sum for the next item.
  • On the first run, total is 0 (the initial value) and score is 10, so the callback returns 10. That 10 becomes the new total for 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.

reduce.js
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); // 47

Let’s break this down step by step:

  • cart is an array of objects, each with a name and a price.
  • cart.reduce((sum, item) => sum + item.price, 0) runs the callback once per item, starting the accumulator at 0.
  • sum is the accumulator (the running total); item is the current cart object.
  • sum + item.price reads 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, so total is 47.

You can also build something other than a number. Here reduce builds a single object that counts how many of each fruit appears.

reduce.js
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:

  • fruits is the array of fruit names, with some repeats we want to count.
  • The initial value is an empty object {}, so the accumulator tally starts as an empty object instead of a number.
  • tally is the running object of counts; fruit is the current fruit name.
  • tally[fruit] = (tally[fruit] || 0) + 1 looks up the current count for that fruit (using 0 if it isn’t there yet) and adds one.
  • return tally hands the same object back so the next iteration keeps building on it. After every fruit, counts holds 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:

reduce.js
const numbers = [1, 2, 3];
// ❌ The callback returns nothing, so the accumulator becomes undefined
numbers.reduce((acc, n) => {
acc + n;
}, 0);
// ✅ The callback returns the accumulator every time
numbers.reduce((acc, n) => {
return acc + n;
}, 0);

Let’s compare the two calls:

  • In the first call, acc + n is computed but never returned, so the callback hands back undefined. On the next iteration acc is undefined, and the math falls apart.
  • In the second call, return acc + n passes the new running total back, so acc carries the correct sum into every iteration.
  • The only difference is the return keyword, 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!

  1. Create an array of numbers and use reduce to add them all together. Start the accumulator at 0.
  2. Trace each step on paper: write the accumulator before and after every item.
  3. Create an array of objects with a price field and use reduce to find the total price.
  4. Remove the initial value from your sum and watch what happens with an empty array.
  5. Use reduce to find the largest number in an array by keeping the bigger value each step.

🧩 What You’ve Learned

  • reduce boils 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 map or filter when reduce would 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.

Share & Connect