Modern JavaScript gives you powerful tools to work with arrays without modifying the original data. These methods follow a functional programming pattern: they take your array, apply a transformation, and return a new result. Once you learn them, you will use them in every project, from rendering lists of React components to transforming APIWhat is api?A set of rules that lets one program talk to another, usually over the internet, by sending requests and getting responses. data before displaying it.
map(): transform every element
map() creates a new array by applying a function to every element:
const prices = [10, 20, 30];
const doubled = prices.map(price => price * 2);
console.log(doubled); // [20, 40, 60]
console.log(prices); // [10, 20, 30] - unchangedThe callbackWhat is callback?A function you pass into another function to be called later, often when an operation finishes or an event occurs. receives the current element, the indexWhat is index?A data structure the database maintains alongside a table so it can find rows by specific columns quickly instead of scanning everything. (optional), and the original array (optional):
const names = ["alice", "bob", "charlie"];
const capitalized = names.map((name, index) => {
return `${index + 1}. ${name.charAt(0).toUpperCase() + name.slice(1)}`;
});
// ["1. Alice", "2. Bob", "3. Charlie"]map() always returns a new array with the same number of elements as the original. If you need to transform and filter at the same time, chain filter() before or after map().
filter(): keep what you need
filter() creates a new array containing only elements that pass a test:
const numbers = [1, 2, 3, 4, 5, 6];
const evens = numbers.filter(n => n % 2 === 0);
console.log(evens); // [2, 4, 6]
const users = [
{ name: "Alice", age: 25 },
{ name: "Bob", age: 17 },
{ name: "Charlie", age: 30 }
];
const adults = users.filter(user => user.age >= 18);
console.log(adults.length); // 2 (Alice and Charlie)The callbackWhat is callback?A function you pass into another function to be called later, often when an operation finishes or an event occurs. must return true or false (or a truthy/falsyWhat is truthy/falsy?How JavaScript treats non-boolean values in conditions: some values act as false (0, empty string, null, undefined, NaN) and everything else acts as true. value). Elements where the callback returns true are kept; the restWhat is rest?An architectural style for web APIs where URLs represent resources (nouns) and HTTP methods (GET, POST, PUT, DELETE) represent actions on those resources. are discarded.
find(): get the first match
Unlike filter() which returns an array, find() returns the first matching element (or undefined if none match):
const users = [
{ id: 1, name: "Alice" },
{ id: 2, name: "Bob" },
{ id: 3, name: "Charlie" }
];
const user = users.find(u => u.id === 2);
console.log(user); // { id: 2, name: "Bob" }
const notFound = users.find(u => u.id === 999);
console.log(notFound); // undefinedUse find() when you expect only one result (like looking up a user by ID). Use filter() when there might be multiple matches.
reduce(): combine into one value
reduce() is the most powerful array method. It combines all elements into a single value using an accumulator:
const numbers = [1, 2, 3, 4, 5];
const sum = numbers.reduce((accumulator, current) => {
return accumulator + current;
}, 0);
console.log(sum); // 15The second argument to reduce() (0 in the example) is the initial value. Always provide it to avoid unexpected behavior on empty arrays.
const products = [
{ name: "Apple", price: 1.50 },
{ name: "Banana", price: 0.75 },
{ name: "Cherry", price: 3.00 }
];
// Calculate total price
const total = products.reduce((sum, product) => sum + product.price, 0);
console.log(total); // 5.25Chaining methods
Since these methods return new arrays, you can chain them together:
const users = [
{ name: "Alice", age: 25, active: true },
{ name: "Bob", age: 17, active: true },
{ name: "Charlie", age: 30, active: false },
{ name: "Diana", age: 22, active: true }
];
const activeAdultNames = users
.filter(u => u.active && u.age >= 18)
.map(u => u.name);
console.log(activeAdultNames); // ["Alice", "Diana"]forEach when map or filter is the right choice, forEach returns undefined and is only for side effects. If you are building a new array, use map or filter, not forEach with push. When you see AI generate const result = []; items.forEach(x => { if (x.active) result.push(x.name); }), rewrite it as const result = items.filter(x => x.active).map(x => x.name).forEach vs map vs filter
This is a common source of confusion:
| Method | Returns | Use when |
|---|---|---|
forEach() | undefined | You need side effects (logging, DOM updates) |
map() | New array (same length) | You need to transform each element |
filter() | New array (subset) | You need to keep some elements |
find() | Single element or undefined | You need one specific element |
reduce() | Any single value | You need to combine all elements |
Other useful methods
| Method | Purpose | Example |
|---|---|---|
some() | Returns true if ANY element passes | arr.some(n => n > 10) |
every() | Returns true if ALL elements pass | arr.every(n => n > 0) |
sort() | Sorts in place (mutates!) | arr.sort((a, b) => a - b) |
slice() | Extracts portion (immutable) | arr.slice(1, 3) |
flat() | Flattens nested arrays | [[1,2], [3,4]].flat() |
join() | Joins into string | ['a','b'].join('-') |
findIndex() | Index of first match | arr.findIndex(x => x > 3) |
Quick reference
| Task | Method | Mutates? |
|---|---|---|
| Transform each item | map() | No |
| Keep matching items | filter() | No |
| Find one item | find() | No |
| Find one index | findIndex() | No |
| Combine into one value | reduce() | No |
| Run side effects | forEach() | No |
| Check if any match | some() | No |
| Check if all match | every() | No |
| Sort in place | sort() | Yes |
| Extract a portion | slice() | No |