Day 8: map, filter, reduce, find & sort
✅ Today you will learn
- forEach vs map: doing vs transforming
- filter, find, findIndex, some, every
- reduce for totals, counts and grouping
- Sorting arrays of objects by price, rating or name
- Chaining methods into readable data pipelines
🏢 In the real world
Mr. Sharma asks for a dashboard: “Show only sweets in stock, sorted by price, with total stock value, and tell me if anything is running low.” With loops this is 40 lines. With map, filter and reduce it is 6 readable lines. These methods are asked in almost every JavaScript interview and are the heart of React code.
forEach and map
const products = [
{ id: 1, name: 'Kaju Katli', category: 'dry', price: 900, rating: 4.8, stock: 25 },
{ id: 2, name: 'Malai Ghewar', category: 'milk', price: 650, rating: 4.7, stock: 8 },
{ id: 3, name: 'Rasmalai', category: 'milk', price: 700, rating: 4.6, stock: 12 },
{ id: 4, name: 'Besan Ladoo', category: 'dry', price: 500, rating: 4.5, stock: 40 },
{ id: 5, name: 'Kalakand', category: 'milk', price: 600, rating: 4.4, stock: 0 },
{ id: 6, name: 'Soan Papdi', category: 'dry', price: 380, rating: 4.1, stock: 60 },
];
products.forEach(p => console.log(`${p.id}. ${p.name}`)); // DO something for each – returns nothing
const names = products.map(p => p.name); // TRANSFORM each – returns a new array
const withGst = products.map(p => ({ name: p.name, price: Math.round(p.price * 1.05) }));
console.log(names);
console.log(withGst.slice(0, 2));filter, find, some, every
const products = [
{ id: 1, name: 'Kaju Katli', category: 'dry', price: 900, rating: 4.8, stock: 25 },
{ id: 2, name: 'Malai Ghewar', category: 'milk', price: 650, rating: 4.7, stock: 8 },
{ id: 3, name: 'Rasmalai', category: 'milk', price: 700, rating: 4.6, stock: 12 },
{ id: 4, name: 'Besan Ladoo', category: 'dry', price: 500, rating: 4.5, stock: 40 },
{ id: 5, name: 'Kalakand', category: 'milk', price: 600, rating: 4.4, stock: 0 },
{ id: 6, name: 'Soan Papdi', category: 'dry', price: 380, rating: 4.1, stock: 60 },
];
const inStock = products.filter(p => p.stock > 0);
const milkSweets = products.filter(p => p.category === 'milk');
console.log(inStock.length, 'in stock;', milkSweets.map(p => p.name).join(', '));
const ghewar = products.find(p => p.name.includes('Ghewar')); // first match or undefined
const index = products.findIndex(p => p.id === 5);
console.log(ghewar.price, index);
console.log('Any sold out?', products.some(p => p.stock === 0));
console.log('All rated 4+?', products.every(p => p.rating >= 4));| Method | Returns | Use for |
|---|---|---|
| map(fn) | New array, same length | Transform: prices → labels, data → HTML |
| filter(fn) | New array, 0..n items | Keep matching items: in stock, category |
| find(fn) | First matching item or undefined | Look up one product by id |
| findIndex(fn) | Index or -1 | Update/remove an item in place |
| some(fn) | true/false – at least one | “Is anything sold out?” |
| every(fn) | true/false – all | “Are all fields filled?” |
| reduce(fn, start) | One value (number, object…) | Totals, counts, grouping |
| forEach(fn) | undefined | Side effects only (logging, DOM updates) |
reduce – many values into one
const products = [
{ id: 1, name: 'Kaju Katli', category: 'dry', price: 900, rating: 4.8, stock: 25 },
{ id: 2, name: 'Malai Ghewar', category: 'milk', price: 650, rating: 4.7, stock: 8 },
{ id: 3, name: 'Rasmalai', category: 'milk', price: 700, rating: 4.6, stock: 12 },
{ id: 4, name: 'Besan Ladoo', category: 'dry', price: 500, rating: 4.5, stock: 40 },
{ id: 5, name: 'Kalakand', category: 'milk', price: 600, rating: 4.4, stock: 0 },
{ id: 6, name: 'Soan Papdi', category: 'dry', price: 380, rating: 4.1, stock: 60 },
];
// reduce((accumulator, item) => newAccumulator, startValue)
const stockValue = products.reduce((sum, p) => sum + p.price * p.stock, 0);
console.log('Stock value: ₹' + stockValue.toLocaleString('en-IN'));
const countByCategory = products.reduce((acc, p) => {
acc[p.category] = (acc[p.category] || 0) + 1;
return acc;
}, {});
console.log(countByCategory);
const cheapest = products.reduce((min, p) => (p.price < min.price ? p : min));
console.log('Cheapest:', cheapest.name);
const cart = [{ id: 1, qty: 2 }, { id: 4, qty: 1.5 }];
const cartTotal = cart.reduce((sum, line) => sum + products.find(p => p.id === line.id).price * line.qty, 0);
console.log('Cart total: ₹' + cartTotal);Without the second argument reduce uses the first item as the start, which crashes on an empty array (“Reduce of empty array with no initial value”) and breaks when items are objects. 0 for sums, {} for grouping, [] for lists.
Sorting arrays of objects
const products = [
{ id: 1, name: 'Kaju Katli', category: 'dry', price: 900, rating: 4.8, stock: 25 },
{ id: 2, name: 'Malai Ghewar', category: 'milk', price: 650, rating: 4.7, stock: 8 },
{ id: 3, name: 'Rasmalai', category: 'milk', price: 700, rating: 4.6, stock: 12 },
{ id: 4, name: 'Besan Ladoo', category: 'dry', price: 500, rating: 4.5, stock: 40 },
{ id: 5, name: 'Kalakand', category: 'milk', price: 600, rating: 4.4, stock: 0 },
{ id: 6, name: 'Soan Papdi', category: 'dry', price: 380, rating: 4.1, stock: 60 },
];
const byPrice = [...products].sort((a, b) => a.price - b.price);
const byRating = [...products].sort((a, b) => b.rating - a.rating);
const byName = [...products].sort((a, b) => a.name.localeCompare(b.name));
console.log(byPrice.map(p => `${p.name} ₹${p.price}`).join(' < '));
console.log(byRating[0].name, 'is top rated');
console.log(byName.map(p => p.name)[0]);Chaining: a data pipeline
const products = [
{ id: 1, name: 'Kaju Katli', category: 'dry', price: 900, rating: 4.8, stock: 25 },
{ id: 2, name: 'Malai Ghewar', category: 'milk', price: 650, rating: 4.7, stock: 8 },
{ id: 3, name: 'Rasmalai', category: 'milk', price: 700, rating: 4.6, stock: 12 },
{ id: 4, name: 'Besan Ladoo', category: 'dry', price: 500, rating: 4.5, stock: 40 },
{ id: 5, name: 'Kalakand', category: 'milk', price: 600, rating: 4.4, stock: 0 },
{ id: 6, name: 'Soan Papdi', category: 'dry', price: 380, rating: 4.1, stock: 60 },
];
const report = products
.filter(p => p.stock > 0) // 1. only available
.sort((a, b) => a.price - b.price) // 2. cheapest first
.map(p => `${p.name.padEnd(13)} ₹${p.price} ${p.stock < 10 ? '⚠️ low stock' : ''}`); // 3. format
console.log(report.join('\n'));Real task: live product filter
<input id="q" placeholder="Search sweets…" aria-label="Search">
<select id="cat" aria-label="Category"><option value="">All</option><option value="milk">Milk</option><option value="dry">Dry</option></select>
<select id="sort" aria-label="Sort"><option value="">Sort</option><option value="low">Price ↑</option><option value="high">Price ↓</option><option value="rating">Rating</option></select>
<p id="summary"></p>
<ul id="list"></ul>
<script>
const products = [
{ id: 1, name: 'Kaju Katli', category: 'dry', price: 900, rating: 4.8, stock: 25 },
{ id: 2, name: 'Malai Ghewar', category: 'milk', price: 650, rating: 4.7, stock: 8 },
{ id: 3, name: 'Rasmalai', category: 'milk', price: 700, rating: 4.6, stock: 12 },
{ id: 4, name: 'Besan Ladoo', category: 'dry', price: 500, rating: 4.5, stock: 40 },
{ id: 5, name: 'Kalakand', category: 'milk', price: 600, rating: 4.4, stock: 0 },
{ id: 6, name: 'Soan Papdi', category: 'dry', price: 380, rating: 4.1, stock: 60 },
];
function render() {
const q = document.querySelector('#q').value.trim().toLowerCase();
const cat = document.querySelector('#cat').value;
const sort = document.querySelector('#sort').value;
let result = products
.filter(p => p.name.toLowerCase().includes(q))
.filter(p => cat === '' || p.category === cat);
if (sort === 'low') result = [...result].sort((a, b) => a.price - b.price);
if (sort === 'high') result = [...result].sort((a, b) => b.price - a.price);
if (sort === 'rating') result = [...result].sort((a, b) => b.rating - a.rating);
const avg = result.length ? result.reduce((s, p) => s + p.price, 0) / result.length : 0;
document.querySelector('#summary').textContent = `${result.length} sweets · average ₹${Math.round(avg)}/kg`;
document.querySelector('#list').innerHTML = result
.map(p => `<li>${p.name} – ₹${p.price} ★${p.rating} ${p.stock === 0 ? '<b>(sold out)</b>' : ''}</li>`)
.join('') || '<li>No sweets match</li>';
}
document.querySelectorAll('#q, #cat, #sort').forEach(el => el.addEventListener('input', render));
render();
</script>🏅 Job skills unlocked today
Practice tasks
🏋️ Practice – do it yourself
Show solution
const marks = [{ name: 'Aarav', m: 72 }, { name: 'Riya', m: 91 }, { name: 'Kabir', m: 28 }, { name: 'Sana', m: 64 }];
const passed = marks.filter(s => s.m >= 33).map(s => s.name);
const average = marks.reduce((sum, s) => sum + s.m, 0) / marks.length;
const topper = marks.reduce((best, s) => (s.m > best.m ? s : best));
console.log('Passed:', passed.join(', '));
console.log('Average:', average.toFixed(2));
console.log('Topper:', topper.name, topper.m);Show solution
const expenses = [{ cat: 'food', amt: 250 }, { cat: 'travel', amt: 120 }, { cat: 'food', amt: 90 }];
const totals = expenses.reduce((acc, e) => {
acc[e.cat] = (acc[e.cat] || 0) + e.amt;
return acc;
}, {});
console.log(totals);Quick quiz
🧠 Quick Quiz – test yourself
Interview corner
💼 Interview Corner
Difference between map and forEach?
map returns a new array of the callback’s return values and is chainable – use it to transform data. forEach returns undefined and is used for side effects. Neither mutates the array by itself.
Implement your own map using reduce.
const map = (arr, fn) => arr.reduce((acc, item, i) => { acc.push(fn(item, i, arr)); return acc; }, []); – reduce can express map and filter because it can build any value.
Summary
- map transforms, filter selects, find picks one, some/every check.
- reduce(fn, start) builds totals, counts and groups.
- Sort objects with a compare function on a copy.
- Chain filter → sort → map for clean data pipelines.
Day 9: strings, numbers, money and dates – formatting rupees, rounding paise correctly and working with delivery dates.
