Frontend Development · Tutorial 5 of 5
JavaScript Array Methods: map, filter and reduce with examples
By the FUTEAC Team · 5 November 2026 · 10 min read · Beginner
In short
map transforms every item in an array into something new, filter keeps only the items that pass a test, and reduce combines all items into a single value. Together they replace most for loops with shorter, clearer code: instead of telling JavaScript *how* to walk through a list, you say *what you want* from the data.
filterselects,maptransforms,reducecombines. That one sentence is the whole mental model — each method does exactly one job.- They return new arrays (or a new value). The original array is never changed, which prevents a whole class of bugs where data silently changes under you.
- Each takes a small function — called once per item — that receives the current item (and its index if you need it).
- They chain.
products.filter(...).map(...)reads like a sentence: "take the products, keep the cheap ones, label them." - This tutorial feeds the JavaScript Essentials course (/course/javascript-essentials — lesson "Arrays and Common Array Methods") and the JavaScript (/skill/javascript) and Modern JavaScript (ES6+) (/skill/javascript-es6) skills.
Before you start
What problem do map, filter and reduce solve?
Almost every app works with lists: products, users, tasks, search results. The classic way to process a list is a for loop with a counter, an empty results array, and a push inside an if:
const names = [];
for (let i = 0; i < products.length; i++) {
if (products[i].inStock) {
names.push(products[i].name.toUpperCase());
}
}It works, but it mixes three concerns — walking the list, deciding what to keep, transforming what you kept — into one block. The array methods split those concerns apart, one method per job, so each line says what it means:
const names = products
.filter(p => p.inStock)
.map(p => p.name.toUpperCase());You will see this style in every modern codebase, in React lists, in API responses processed on the frontend — so it pays to get comfortable with it now.
How does filter work?
filter keeps the items that pass a test and drops the rest. It calls your function once per item; if your function returns true, the item stays.
const prices = [120, 45, 300, 80];
// keep prices under 100
const cheap = prices.filter(price => price < 100);
console.log(cheap); // [ 45, 80 ]Two facts beginners often miss:
filterdoes not change the original array.pricesis still[120, 45, 300, 80]after the call. The result is a *new* array.- The test can be anything that returns true or false: a comparison, a string check, a property lookup (
p.inStock).
How does map work?
map transforms every item into something new and returns an array of the results — always the *same length* as the input.
const prices = [120, 45, 300, 80];
// turn each price into a label
const labels = prices.map(price => `Rs ${price}`);
console.log(labels); // [ 'Rs 120', 'Rs 45', 'Rs 300', 'Rs 80' ]map shines when data arrives in one shape (an API response) and your page needs another (rendered rows, labels, option elements). The original array stays untouched; prices is unchanged.
How does reduce work?
reduce combines all items into a single value — a total, a string, an object, anything. It carries an "accumulator" from one item to the next:
const prices = [120, 45, 300, 80];
// add everything up, starting from 0
const total = prices.reduce((sum, price) => sum + price, 0);
console.log(total); // 545Read it as: "start with sum = 0; for each price, sum becomes sum + price; hand me the final sum." The second argument (0) is the initial value — always pass it. Without it, reduce uses the first item as the start, which throws an error on an empty array and gives surprising results when types differ (see Common mistakes).
How do you chain them together?
Because each method returns an array, you can feed one into the next in a single expression. Read it left to right:
const prices = [120, 45, 300, 80];
const result = prices
.filter(price => price < 100) // [45, 80]
.map(price => `Rs ${price}`); // ['Rs 45', 'Rs 80']
console.log(result); // [ 'Rs 45', 'Rs 80' ]The filter runs first on the full array, then map runs on the filtered result. Nothing in between is stored in a variable — but you *can* split it into named steps while learning, exactly as the worked example below does.
Worked example: a small shop's product list
A shop keeps its products as an array of objects. Three questions: which products are in stock, what should their price labels say, and what is the total value of the in-stock inventory? One method per question.
const products = [
{ name: "Mouse", price: 1500, inStock: true },
{ name: "Keyboard", price: 3200, inStock: true },
{ name: "Monitor", price: 28000, inStock: false },
{ name: "Webcam", price: 6500, inStock: true },
];
// 1. filter — keep only the products that are in stock
const inStock = products.filter(p => p.inStock);
// 2. map — turn each product into a readable price label
const labels = inStock.map(p => `${p.name}: Rs ${p.price}`);
// 3. reduce — add up the prices of the in-stock products
const total = inStock.reduce((sum, p) => sum + p.price, 0);
console.log("in stock:", inStock.map(p => p.name));
console.log("labels:", labels);
console.log("total value of in-stock products: Rs", total);
// 4. chaining — filter + map in one expression, no intermediate variable
const cheapLabels = products
.filter(p => p.inStock && p.price < 5000)
.map(p => p.name.toUpperCase());
console.log("cheap in-stock:", cheapLabels);Exact output when run (Node.js v24.22.1):
in stock: [ 'Mouse', 'Keyboard', 'Webcam' ]
labels: [ 'Mouse: Rs 1500', 'Keyboard: Rs 3200', 'Webcam: Rs 6500' ]
total value of in-stock products: Rs 11200
cheap in-stock: [ 'MOUSE', 'KEYBOARD' ]Notice what to read from the output: the Monitor (out of stock) never appears; the labels keep the original prices; 1500 + 3200 + 6500 = 11200; and the chained version filters on *two* conditions at once, then maps to uppercase names.
shown underneath, plus one expanded array item to show the console's array rendering. Filename suggestion: javascript-array-methods-devtools-console.png`; alt text: "Browser developer console showing a chained filter and map expression on a products array and its result."]
Try it yourself
A class has test scores. From this data, answer three questions with the three methods: ``js const scores = [ { name: "Ali", score: 82 }, { name: "Sara", score: 47 }, { name: "Bilal", score: 65 }, { name: "Hina", score: 91 }, { name: "Omar", score: 38 }, ]; ` 1. filter the students who passed (score 50 or more). 2. map the passing students to just their names, in uppercase. 3. reduce all five scores to the class average (sum divided by scores.length). Expected answers: 3 students passed; names ['ALI', 'BILAL', 'HINA']; average is 64.6. If your average comes out wrong, check that your initial value is 0` and that you divide by the *full* array's length, not the filtered one.
Common mistakes
- Forgetting
returnin a block-body arrow function.p => p.inStockreturns the value automatically, butp => { p.inStock }with braces returnsundefined— andfilterdrops *everything*. With braces, writereturnexplicitly. - Using
mapfor side effects. If you only want to *do* something with each item (log it, save it, update the DOM) and don't need a new array, useforEach, notmap.mapthat ignores its return value is a code smell reviewers will flag. - Skipping the initial value in
reduce.[].reduce((a, b) => a + b)throwsTypeError: Reduce of empty array with no initial value. Always pass the second argument —0for sums,""for strings,[]or{}for building collections. - Assuming the original array changed.
filterandmapnever mutate. If your UI doesn't update, the bug is usually that you rendered the old array instead of the new one the method returned.
Frequently asked questions
When should I use forEach instead of map?
When you want an effect, not a result. forEach runs a function per item and returns nothing — logging, saving to a database, attaching event listeners. map builds a new array. If you find yourself pushing into an outside array inside forEach, you almost certainly wanted map.
Can I use these methods on objects?
Not directly — they are array methods. The usual pattern is Object.keys(obj), Object.values(obj) or Object.entries(obj) to get an array first, then filter/map/reduce over that.
Do map, filter and reduce change the original array?
No. All three are non-mutating: they read the original and hand you something new. (Methods that *do* mutate — sort, splice, push — are a different family, worth learning separately.)
Is chaining slower than one for loop?
For the list sizes a beginner works with, the difference is negligible and readability wins. Chaining walks the array once per method, so in extreme performance-sensitive code a single loop can be faster — but that is an optimisation to reach for only when measurements say so.
Why is it called "reduce"?
Because it *reduces* many values down to one: an array of prices becomes a total, an array of words becomes a sentence, an array of votes becomes a tally object. ---
Follow the Frontend Developer Roadmap
Build modern, responsive websites and web apps with HTML, CSS, JavaScript and React. Free, step by step, at your pace.
View the Roadmap