JavaScript Array Methods Explained: map, filter, reduce, find, and More
JavaScript's built-in array methods are some of the most powerful tools in the language. They replace verbose for loops with declarative, readable code β and they appear constantly in interviews.
This guide covers every essential method with practical examples.
Why Use Array Methods?
Compare these two approaches:
javascript// Imperative β for loop const prices = [10, 25, 5, 40, 15]; const discounted = []; for (let i = 0; i < prices.length; i++) { if (prices[i] > 10) { discounted.push(prices[i] * 0.9); } } // Declarative β array methods const discounted = prices .filter(p => p > 10) .map(p => p * 0.9);
Same result. The second version reads like English: "filter prices above 10, then apply a 10% discount."
map()
map() transforms every element and returns a new array of the same length.
javascriptarray.map(element => newValue)
javascriptconst numbers = [1, 2, 3, 4, 5]; const doubled = numbers.map(n => n * 2); // [2, 4, 6, 8, 10] const users = [ { id: 1, name: "Alice", age: 30 }, { id: 2, name: "Bob", age: 25 }, ]; // Extract one field const names = users.map(u => u.name); // ["Alice", "Bob"] // Transform objects const userCards = users.map(u => ({ id: u.id, label: `${u.name} (${u.age})`, })); // [{ id: 1, label: "Alice (30)" }, { id: 2, label: "Bob (25)" }]
Key rule:
map()always returns an array of the same length. Use it when you need to transform every item. Never use it just for side effects β that is whatforEachis for.
filter()
filter() returns a new array containing only elements that pass a test.
javascriptarray.filter(element => boolean)
javascriptconst numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; const evens = numbers.filter(n => n % 2 === 0); // [2, 4, 6, 8, 10] const products = [ { name: "Laptop", price: 999, inStock: true }, { name: "Mouse", price: 25, inStock: false }, { name: "Monitor", price: 399, inStock: true }, { name: "Desk", price: 250, inStock: false }, ]; // Available products under $500 const available = products .filter(p => p.inStock) .filter(p => p.price < 500); // [{ name: "Monitor", price: 399, inStock: true }]
reduce()
reduce() is the most powerful and most misunderstood array method. It reduces an array to a single value β that value can be a number, string, object, or even a new array.
javascriptarray.reduce((accumulator, currentValue) => newAccumulator, initialValue)
Summing values
javascriptconst numbers = [1, 2, 3, 4, 5]; const sum = numbers.reduce((acc, n) => acc + n, 0); // 15
Building an object from an array
javascriptconst users = [ { id: 1, name: "Alice" }, { id: 2, name: "Bob" }, { id: 3, name: "Carol" }, ]; const userMap = users.reduce((acc, user) => { acc[user.id] = user.name; return acc; }, {}); // { 1: "Alice", 2: "Bob", 3: "Carol" }
Grouping items
javascriptconst orders = [ { product: "Laptop", status: "shipped" }, { product: "Mouse", status: "pending" }, { product: "Monitor", status: "shipped" }, { product: "Desk", status: "cancelled" }, ]; const grouped = orders.reduce((acc, order) => { const key = order.status; acc[key] = acc[key] ? [...acc[key], order] : [order]; return acc; }, {}); // { // shipped: [{ product: "Laptop", ... }, { product: "Monitor", ... }], // pending: [{ product: "Mouse", ... }], // cancelled: [{ product: "Desk", ... }], // }
Always provide an initial value as the second argument to
reduce(). Without it, the first element becomes the initial accumulator and the callback skips it β leading to subtle bugs on empty arrays.
find() and findIndex()
find() returns the first element that passes a test (or undefined). findIndex() returns its index (or -1).
javascriptconst users = [ { id: 1, name: "Alice", role: "admin" }, { id: 2, name: "Bob", role: "user" }, { id: 3, name: "Carol", role: "admin" }, ]; const admin = users.find(u => u.role === "admin"); // { id: 1, name: "Alice", role: "admin" } const bobIndex = users.findIndex(u => u.name === "Bob"); // 1
some() and every()
some() returns true if at least one element passes the test. every() returns true if all elements pass.
javascriptconst scores = [72, 85, 91, 60, 78]; const anyFailing = scores.some(s => s < 65); // true (60 fails) const allPassing = scores.every(s => s >= 60); // true const allExcellent = scores.every(s => s >= 90); // false
These short-circuit β they stop iterating as soon as the result is determined.
flat() and flatMap()
flat() flattens nested arrays. flatMap() maps then flattens one level.
javascript// flat() const nested = [1, [2, 3], [4, [5, 6]]]; nested.flat(); // [1, 2, 3, 4, [5, 6]] β one level nested.flat(2); // [1, 2, 3, 4, 5, 6] β two levels nested.flat(Infinity); // fully flatten any depth // flatMap() β map + flat(1) in one step const sentences = ["Hello world", "Foo bar baz"]; const words = sentences.flatMap(s => s.split(" ")); // ["Hello", "world", "Foo", "bar", "baz"]
forEach()
forEach() runs a callback on each element. It returns undefined β use it for side effects, not transformations.
javascriptconst items = ["apple", "banana", "cherry"]; items.forEach((item, index) => { console.log(`${index + 1}. ${item}`); }); // 1. apple // 2. banana // 3. cherry
Use
map()when you need the returned array. UseforEach()for pure side effects like logging, updating the DOM, or calling an external function.
includes() and indexOf()
javascriptconst fruits = ["apple", "banana", "cherry"]; fruits.includes("banana"); // true fruits.includes("grape"); // false fruits.indexOf("cherry"); // 2 fruits.indexOf("grape"); // -1
sort()
sort() sorts in place (mutates the original array) and converts elements to strings by default β which breaks numeric sorting.
javascript// String sort (alphabetical β default) ["banana", "apple", "cherry"].sort(); // ["apple", "banana", "cherry"] // Numeric sort β MUST provide comparator [10, 1, 25, 3].sort((a, b) => a - b); // [1, 3, 10, 25] β ascending [10, 1, 25, 3].sort((a, b) => b - a); // [25, 10, 3, 1] β descending // Sort objects by a field const users = [ { name: "Carol", age: 28 }, { name: "Alice", age: 35 }, { name: "Bob", age: 22 }, ]; users.sort((a, b) => a.age - b.age); // [Bob 22, Carol 28, Alice 35]
Chaining Methods
The real power comes from chaining:
javascriptconst orders = [ { id: 1, amount: 150, status: "completed", customerId: 3 }, { id: 2, amount: 50, status: "pending", customerId: 1 }, { id: 3, amount: 300, status: "completed", customerId: 3 }, { id: 4, amount: 80, status: "completed", customerId: 2 }, ]; // Total revenue from completed orders over $100 const revenue = orders .filter(o => o.status === "completed") .filter(o => o.amount > 100) .map(o => o.amount) .reduce((sum, amount) => sum + amount, 0); // 450
Common Interview Questions
Q: What is the difference between map() and forEach()?
map() returns a new array of transformed values. forEach() returns undefined β it is only for side effects.
Q: What is the difference between find() and filter()?
find() returns the first matching element (or undefined). filter() returns all matching elements as an array (or an empty array).
Q: How would you remove duplicates from an array?
javascriptconst nums = [1, 2, 2, 3, 3, 4]; const unique = [...new Set(nums)]; // [1, 2, 3, 4]
Q: Does sort() mutate the original array?
Yes. To sort without mutation, spread first: [...arr].sort((a, b) => a - b).
Practice JavaScript on Froquiz
Array methods come up in almost every JavaScript interview. Test your JavaScript skills on Froquiz β we cover array methods, closures, the event loop, async patterns, and much more.
Summary
- map() β transform every element, same-length array returned
- filter() β keep elements that pass a test
- reduce() β accumulate to a single value (number, object, array)
- find() β first matching element; findIndex() β its index
- some() β any element passes; every() β all elements pass
- flat() β flatten nested arrays; flatMap() β map then flatten
- forEach() β side effects only, returns undefined
- sort() β in-place, always provide a comparator for numbers
Chain these methods and you will write cleaner, more expressive JavaScript than 90% of developers.