map, filter & reduce
These three array methods are the heart of modern, professional JavaScript. They let you express "transform this", "keep these", and "summarise that" declaratively — you describe the result instead of writing fiddly for loops with index bookkeeping.
Learn map, filter & reduce in our free JavaScript course — a beginner-friendly interactive lesson with runnable examples, a practice exercise and a quick…
Part of the free JavaScript course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
Master this trio and you'll read and write real-world data code — turning API responses into UI, totals, and reports — with confidence.
📚 Prerequisites: You should be comfortable with arrays and functions — especially arrow functions, since the callbacks here are almost always arrows.
💡 Running Code Locally: While this online editor runs real JavaScript, some advanced examples may have limitations. For the best experience:
🏭 Real-World Analogy: Picture a factory conveyor belt of items:
map runs your callback on every element and collects the returned values into a new array of the same length . The original is untouched. Use it whenever you need "the same list, but reshaped" — prices with tax, names from user objects, labels for a dropdown.
filter keeps every item for which your callback returns a truthy value and drops the rest. The result is a new array that's the same length or shorter — never longer, and never reshaped. Think "show only the items matching this condition".
Filter to the even numbers, then map them to double their value.
reduce is the most powerful of the three. It carries an accumulator from item to item, and your callback returns the updated accumulator each time. The signature is array.reduce((acc, item) => newAcc, startValue) . Always pass a start value — it sets the type and protects against empty arrays.
The accumulator doesn't have to be a number. Start with an empty object {' '} and you can group , count , or index data — patterns you'll reach for constantly when shaping API responses for the screen.
Because filter and map return arrays, you can chain them and finish with reduce . Reading top to bottom, the data flows through each stage like a pipeline — this is the everyday shape of real data code.
Complete the reduce so it adds every number, starting from 0.
These lines are scrambled. Reorder them so the pipeline logs 30 .
Why: each stage feeds the next — filter (→ [2,4]) before map (→ [4,8]) before reduce (→ 30) before logging.
Predict the output before revealing the answer.
[ 2, 3, 4 ] — map returns a new array of the same length, each item transformed.
2 — only 8 and 11 pass the test, so the new array has length 2.
10 — reduce sums the array starting from 0: 0+1+2+3+4.
Up next: Hoisting — why some code runs before you'd expect. ⬆️
Practice quiz
What does map return?
- A single value
- The original array, mutated
- A new array of the same length, each item transformed
- Only the items that pass a test
Answer: A new array of the same length, each item transformed. map transforms every element and returns a new array of the same length.
What does [1, 2, 3].map(n => n + 1) log?
map adds 1 to each element, producing [2, 3, 4].
What does filter keep?
- The first matching item only
- Items reshaped by the callback
- A single accumulated value
- Items for which the callback returns a truthy value
Answer: Items for which the callback returns a truthy value. filter keeps every item whose callback returns truthy and drops the rest.
What is [5, 8, 11].filter(n => n > 7).length?
- 1
- 2
- 3
- 0
Answer: 2. Only 8 and 11 pass the test, so the new array has length 2.
What does [1, 2, 3, 4].reduce((a, b) => a + b, 0) return?
- 10
- 0
- 4
Answer: 10. reduce sums the array starting from 0: 0+1+2+3+4 = 10.
What is the second argument to reduce?
- The callback
- The array length
- The starting value of the accumulator
- The current index
Answer: The starting value of the accumulator. The second argument is the start value; always pass it so empty arrays do not throw and the type is clear.
Do map and filter mutate the original array?
- Yes, both mutate
- No, both return a new array
- Only filter mutates
- Only map mutates
Answer: No, both return a new array. Both are non-mutating: they return a brand-new array and leave the original unchanged.
Why might a map produce all undefined values?
- The array was empty
- filter was used instead
- reduce had no start value
- The callback uses a block body { } without a return
Answer: The callback uses a block body { } without a return. A block-body arrow like n => { n * 2; } returns nothing; use n => n * 2 or add an explicit return.
What does orders.filter(o => o.paid).map(o => o.price).reduce((s, p) => s + p, 0) compute?
- The count of paid orders
- The total price of paid orders only
- All prices summed
- The most expensive order
Answer: The total price of paid orders only. The pipeline keeps paid orders, pulls their prices, then sums them.
Which method should you use only for side effects like logging?
- map
- filter
- forEach
- reduce
Answer: forEach. forEach returns undefined and is meant for side effects; using map for logging builds a junk array.