In short
JavaScript array methods like map, filter, reduce, find and forEach let you transform, search and total lists with short, readable code instead of manual loops. Why use array methods instead of for loops? You already know how to loop over a list with a for loop.
JavaScript array methods like map, filter, reduce, find and forEach let you transform, search and total lists with short, readable code instead of manual loops.
Why use array methods instead of for loops?
You already know how to loop over a list with a for loop. That works, but you have to manage a counter, check the length and build results by hand. Array methods do that work for you. You just pass in a function that says what to do with each item. A function you pass into another function is called a callback.
We will use this product list in every example. Each product is an object (a group of named values in curly braces). You will study objects in depth in the next module; for now, just know that product.price reads the price.
const products = [
{ name: "T-shirt", price: 15, inStock: true },
{ name: "Jeans", price: 45, inStock: false },
{ name: "Sneakers", price: 80, inStock: true },
{ name: "Cap", price: 12, inStock: true },
];
forEach: do something with every item
forEach runs your callback once for each element. It does not return anything useful (it returns undefined). Use it when you want a side effect, like logging or updating the page.
products.forEach((product, index) => {
console.log(`${index + 1}. ${product.name} - $${product.price}`);
});
// Output:
// 1. T-shirt - $15
// 2. Jeans - $45
// 3. Sneakers - $80
// 4. Cap - $12
The callback gets the current item and, optionally, its index. We add 1 to the index so the list starts at 1 for humans.
map and filter: build a new array
map creates a new array of the same length, where each item is the result of your callback. Use it to transform data.
filter creates a new array with only the items where your callback returns true. Use it to keep some items and drop others.
const names = products.map((product) => product.name);
console.log(names);
// Output: ["T-shirt", "Jeans", "Sneakers", "Cap"]
const salePrices = products.map((product) => product.price / 2);
console.log(salePrices);
// Output: [7.5, 22.5, 40, 6]
const available = products.filter((product) => product.inStock);
console.log(available.length);
// Output: 3
const cheap = products.filter((product) => product.price < 20);
console.log(cheap.map((p) => p.name));
// Output: ["T-shirt", "Cap"]
The original products array is not changed by any of these. That is important: you can always go back to the full list.
Common mistake: Forgetting to
returna value when the arrow function has curly braces.products.map((p) => { p.name; })gives[undefined, undefined, ...]. Write(p) => p.nameor(p) => { return p.name; }.
find, findIndex, some and every: search an array
Sometimes you want one item, not a new list.
findreturns the first item that matches, orundefined.findIndexreturns the index of the first match, or-1.somereturnstrueif at least one item matches.everyreturnstrueonly if all items match.
const jeans = products.find((p) => p.name === "Jeans");
console.log(jeans.price);
// Output: 45
const capIndex = products.findIndex((p) => p.name === "Cap");
console.log(capIndex);
// Output: 3
console.log(products.some((p) => p.price > 50)); // Output: true
console.log(products.every((p) => p.inStock)); // Output: false
some is great for questions like "is anything out of stock?" and every for "did the user fill in every field?".
reduce: turn an array into one value
reduce walks through the array and builds up a single result, like a running total. Its callback gets two main values: the accumulator (the result so far) and the current item. The second argument to reduce is the starting value.
Here is a shopping cart total:
const cart = [
{ name: "T-shirt", price: 15, qty: 2 },
{ name: "Cap", price: 12, qty: 1 },
{ name: "Sneakers", price: 80, qty: 1 },
];
const total = cart.reduce((sum, item) => sum + item.price * item.qty, 0);
console.log(`Total: $${total}`);
// Output: Total: $122
Step by step: sum starts at 0. Then it becomes 0 + 30 = 30, then 30 + 12 = 42, then 42 + 80 = 122.
Tip: Always pass a starting value (like
0) toreduce. Without it,reduceuses the first element as the start, which breaks with objects and throws an error on an empty array.
How to chain array methods
Because map and filter return arrays, you can call another method right after them. This is called chaining. Let's get the total price of everything that is in stock:
const stockValue = products
.filter((p) => p.inStock)
.map((p) => p.price)
.reduce((sum, price) => sum + price, 0);
console.log(stockValue);
// Output: 107
Read it top to bottom: keep in-stock products, take their prices, add them up (15 + 80 + 12). Putting each method on its own line keeps the chain easy to read.
Here is a quick summary of what each method gives back:
| Method | Returns | New array? |
|---|---|---|
forEach | undefined | No |
map | Array of same length | Yes |
filter | Array of matching items | Yes |
find | One item or undefined | No |
findIndex | A number (or -1) | No |
some / every | true or false | No |
reduce | Any single value | No (unless you build one) |
None of these methods change the original array.
Practice exercise
Use the products array from this lesson.
- Use
mapto make an array of strings like"T-shirt: $15". - Use
filterto get products that cost more than $20. - Use
findto get the first product that is out of stock and log its name. - Use
reduceto find the average price of all products.
Hint: For the average, total the prices with reduce, then divide by products.length.
Key takeaways
forEachruns code for each item and returns nothing.maptransforms every item andfilterkeeps some items; both return new arrays.find,findIndex,someandeveryanswer search questions.reducecombines all items into one value; always give it a starting value.- You can chain methods that return arrays to build clear data pipelines.