One value out
map and filter give arrays back. reduce combines all the items into one result: a total, a maximum, a combined string.
const nums = [1, 2, 3, 4]; const sum = nums.reduce((total, n) => total + n, 0); // 10
Two arguments to reduce:
- An arrow taking
(accumulator, item). The accumulator is the running result so far. Whatever the arrow returns becomes the accumulator for the next item. - The starting value for the accumulator (
0here).
Trace the sum: start 0, then 0+1=1, 1+2=3, 3+3=6, 6+4=10. It is exactly the sum loop from lesson 4-3, with the machinery folded in. If reduce feels dense, write the loop first and translate. Both are correct, and reduce is the one you will read constantly in other people's code.
Summing and maximizing with the same method
Two reduces over one array. The first combines with addition and the second combines with Math.max, which shows that the combining step can be any function of two values.
const nums = [7, 2, 9, 4]; const sum = nums.reduce((total, n) => total + n, 0); console.log(sum); const max = nums.reduce((best, n) => Math.max(best, n), nums[0]); console.log(max);
Output
22 9
The sum begins at 0 and folds each number in, reaching 22. The maximum begins at nums[0], which is 7, and each step keeps the larger of the running best and the current item using Math.max from lesson 1-2.
Comparing the two lines side by side is the fastest way to internalize reduce. Only two things changed: the operation inside the arrow and the starting value. Everything else about the mechanism is identical, which is why one method can express totals, maximums, counts, and joined strings.
Totaling a cart with reduce
The sum pattern applied to prices. This is the same job the hand-written loop did in lesson 4-3, now as a single expression.
const cart = [3, 12.5, 7]; const total = cart.reduce((total, price) => total + price, 0); console.log(total);
Output
22.5The shape to memorize is cart.reduce((total, price) => total + price, 0), and the easiest way to read it is to name its three parts. The first parameter is the running result, the second is the current item, and the 0 at the end is where the running result begins.
Starting at 0 is what makes an empty cart total 0 instead of throwing. That is a real advantage over the loop version, where forgetting to initialize the accumulator produces undefined and then NaN.
Reducing to the longest word
Not every reduce produces a number. Here the accumulator holds a word, specifically the longest one seen so far, and each step returns whichever of the two candidates is longer.
const words = ["map", "filter", "reduce", "of"]; const longest = words.reduce((best, w) => (w.length > best.length ? w : best), words[0]); console.log(longest);
Output
filter
The arrow compares lengths but returns a word, using the conditional operator from lesson 3-1: w.length > best.length ? w : best. That asymmetry between what is compared and what is returned is what makes this pattern worth learning.
The result is filter rather than reduce, even though both have six letters, because the comparison uses a strict >. When lengths tie, best wins and the earlier word keeps the title.
Starting from words[0] is the same trick the maximum used earlier: seed the accumulator with a real item so the first comparison has something valid to work against.
The product pattern
Multiplying an array together is summing with two changes, a * in place of the + and a starting value of 1:
const nums = [2, 3, 4]; const product = nums.reduce((acc, n) => acc * n, 1); console.log(product);
Output
24Tracing the accumulator makes it concrete. It starts at 1, then becomes 1 × 2 = 2, then 2 × 3 = 6, then 6 × 4 = 24.
The starting value has to be 1 here, and that is the interesting part. Starting at 0 would make every product zero, because 0 × 2 is 0 and nothing recovers from it. Each combining operation has a value that leaves its input unchanged, which is 0 for addition and 1 for multiplication, and that is the value a reduce should start from.
| Goal | Combining arrow | Start value |
|---|---|---|
| sum | (acc, n) => acc + n | 0 |
| product | (acc, n) => acc * n | 1 |
| maximum | (acc, n) => Math.max(acc, n) | nums[0] |
| joined text | (acc, s) => acc + s | "" |