Difficulty: Beginner
Explain the key array methods in JavaScript. How do map, filter, and reduce differ?
JavaScript arrays have powerful built-in methods that enable functional-style programming. The three most important are map, filter, and reduce.
map() transforms each element and returns a new array of the same length. filter() returns a new array containing only elements that pass a test function. reduce() accumulates all elements into a single value using an accumulator.
Other essential methods include find() (first match), findIndex() (index of first match), some() (any match?), every() (all match?), flat() (flatten nested arrays), flatMap() (map + flatten), and sort() (in-place sorting). Understanding method chaining - combining these methods - is critical for writing clean, readable code.
const products = [
{ name: 'Laptop', price: 999, inStock: true },
{ name: 'Phone', price: 699, inStock: false },
{ name: 'Tablet', price: 499, inStock: true },
{ name: 'Watch', price: 299, inStock: true }
];
// map - transform each element
const names = products.map(p => p.name);
console.log(names);
// filter - keep elements matching condition
const available = products.filter(p => p.inStock);
console.log(available.map(p => p.name));
// reduce - accumulate into single value
const totalValue = products.reduce((sum, p) => sum + p.price, 0);
console.log(`Total: ${totalValue}`);
map returns a new array of same length. filter returns a subset. reduce collapses everything into one value. None mutate the original array.
const orders = [
{ item: 'Book', qty: 2, price: 15 },
{ item: 'Pen', qty: 10, price: 2 },
{ item: 'Laptop', qty: 1, price: 999 },
{ item: 'Notebook', qty: 5, price: 8 }
];
// Chain: filter expensive items, calculate totals, sum them
const expensiveTotal = orders
.filter(o => o.price > 10)
.map(o => o.qty * o.price)
.reduce((sum, total) => sum + total, 0);
console.log(`Expensive items total: ${expensiveTotal}`);
// Group by price range using reduce
const grouped = orders.reduce((acc, o) => {
const range = o.price >= 100 ? 'expensive' : 'affordable';
(acc[range] = acc[range] || []).push(o.item);
return acc;
}, {});
console.log(grouped);
Chaining filter -> map -> reduce is the most common pattern. Reduce is versatile - it can group, flatten, count, or build any data structure.
const nums = [1, 2, 3, 4, 5];
// find - first match
console.log(nums.find(n => n > 3)); // 4
// findIndex - index of first match
console.log(nums.findIndex(n => n > 3)); // 3
// some - at least one passes?
console.log(nums.some(n => n > 4)); // true
// every - all pass?
console.log(nums.every(n => n > 0)); // true
console.log(nums.every(n => n > 3)); // false
// flat - flatten nested arrays
const nested = [1, [2, 3], [4, [5, 6]]];
console.log(nested.flat()); // [1, 2, 3, 4, [5, 6]]
console.log(nested.flat(Infinity)); // [1, 2, 3, 4, 5, 6]
// flatMap - map then flatten one level
const sentences = ['hello world', 'foo bar'];
console.log(sentences.flatMap(s => s.split(' ')));
find returns the element (not a boolean). some/every return booleans. flat accepts a depth argument. flatMap is equivalent to map().flat(1).
map, filter, reduce, forEach, find, Array Chaining