map, filter, and reduce are the three core array transformation methods in JavaScript. map transforms each item, filter keeps some items, and reduce can build any result by accumulating values. Understanding them is essential for clean, functional-style data processing.
map vs filter vs reduce in JavaScript (Array Transformations)
Use guided tracks for structured prep, then practice company-specific question sets when you want targeted interview coverage.
The mental model
These three methods are about transforming arrays without mutating them:
map: "For every item, produce a new item."filter: "Keep only the items that pass a test."reduce: "Combine all items into a single result."
They are the foundation of functional-style programming in JavaScript.
Method | Input → Output | Callback returns | Typical use |
|---|---|---|---|
map | Array → Array (same length) | The new element | Transform each element (e.g., numbers → strings) |
filter | Array → Array (shorter or same) |
| Select a subset (e.g., only active users) |
reduce | Array → Any (number, object, array, map, etc.) | The new accumulator | Aggregate / fold data into one value |
map: transform each element
const numbers = [1, 2, 3];
const doubled = numbers.map(n => n * 2);
// [2, 4, 6]
// Same length, new values
filter: keep some elements
const numbers = [1, 2, 3, 4, 5];
const evens = numbers.filter(n => n % 2 === 0);
// [2, 4]
// Only elements that pass the condition stay
reduce: build anything
const numbers = [1, 2, 3, 4];
const sum = numbers.reduce((acc, n) => acc + n, 0);
// 10
// acc is the running total
reduce can replace both (but shouldn’t always)
You can implement map and filter with reduce, but it’s usually less readable:
// map with reduce
const doubled2 = numbers.reduce((acc, n) => {
acc.push(n * 2);
return acc;
}, []);
// filter with reduce
const evens2 = numbers.reduce((acc, n) => {
if (n % 2 === 0) acc.push(n);
return acc;
}, []);
Common mistakes
1) Forgetting the initial value in reduce: Can cause bugs with empty arrays and wrong types.
2) Mutating the accumulator or items: Breaks immutability and can cause hard-to-track bugs in UI state.
3) Overusing reduce: If map or filter expresses the intent, use them.
Real-world examples
const users = [
{ id: 1, name: 'Alice', active: true },
{ id: 2, name: 'Bob', active: false },
{ id: 3, name: 'Carol', active: true }
];
// 1) Get names of active users
const activeNames = users
.filter(u => u.active)
.map(u => u.name);
// ['Alice', 'Carol']
// 2) Index by id (reduce → object)
const byId = users.reduce((acc, u) => {
acc[u.id] = u;
return acc;
}, {});
// { '1': {...}, '2': {...}, '3': {...} }
Performance note
Chaining filter().map() loops twice. In hot paths, a single reduce can be faster. But in normal code, readability beats micro-optimizations.
One-sentence answer
map transforms each element, filter selects some elements, and reduce combines all elements into a single result of any type.