Advanced Array Methods
Introduction
What You Already Know
In Callbacks and Array Methods, you learned that instead of writing loops ➿ by hand, you can pass a callback to map or filter and describe what you want instead of how to do it.
That pattern doesn't change. This lesson adds three more methods that follow the same idea — with one twist for reduce.
What You'll Learn Today
- How
reducecollapses an array down to a single value - How
mapsets you up for building UIs with real data - Quick coverage of
sort,find, andsome/every
Before You Begin
Accept the GitHub Classroom assignment and clone the repository. Follow the README.md to get set up.
reduce: Collapse an Array to One Value
map returns a new array. filter returns a new array. reduce returns a single value — a number, a string, an object, anything.
The classic example is summing an array of numbers:
const ratings = [9.0, 7.8, 8.6, 7.5, 8.6];
const total = ratings.reduce((sum, current) => sum + current, 0);
console.log(total); // 41.5
The Two Parameters
The callback for reduce receives two parameters instead of one:
sum— the running result so far. Technically, this is called the accumulator because it accumulates the result as you go, butsumis a common name when you're doing addition.current— the current item in the array
On each iteration, whatever you return becomes the new sum for the next iteration.
The Initial Value
Notice the 0 after the callback — that's the initial value. It's what sum starts as before the first item is processed.
Always provide an initial value. It makes the behavior predictable and avoids bugs:
const ratings = [9.0, 7.8, 8.6];
// ✅ With initial value — accumulator starts at 0
ratings.reduce((acc, cur) => acc + cur, 0); // 25.4
// ❌ Without initial value — accumulator starts as the first item
// This works for simple sums but can cause subtle bugs in other cases
ratings.reduce((acc, cur) => acc + cur);
Get in the habit of always initializing.
Walking Through It
const ratings = [9.0, 7.8, 8.6];
ratings.reduce((acc, cur) => acc + cur, 0);
// 3️⃣ elements in the array, 3 iterations of the callback:
// Step 1: acc = 0, cur = 9.0 → returns 9.0
// Step 2: acc = 9.0, cur = 7.8 → returns 16.8
// Step 3: acc = 16.8, cur = 8.6 → returns 25.4
//
// Final result: 25.4
Practice 1: Sum and Average
const scores = [88, 92, 75, 95, 61, 84];
- Use
reduceto get the total of all scores. - Use that total to calculate the average. Log both.
Hint
The average is just total / scores.length. Get the total with reduce first, then divide.
Solution
const scores = [88, 92, 75, 95, 61, 84];
const total = scores.reduce((acc, cur) => acc + cur, 0);
const average = total / scores.length;
console.log(total); // 495
console.log(average); // 82.5
Practice 2: Reduce with Objects
reduce works on arrays of objects too. Here, the accumulator starts as 0 and we pull the value we want from each object.
const cart = [
{ name: "Keyboard", price: 49 },
{ name: "Mouse", price: 25 },
{ name: "Monitor", price: 299 },
{ name: "Webcam", price: 79 },
];
Use reduce to calculate the total price of all items in the cart.
Hint
Your callback receives the accumulator and one cart item at a time. Add item.price to the accumulator on each step.
Solution
const total = cart.reduce((acc, item) => acc + item.price, 0);
console.log(total); // 452
map and Real Data
You've used map to transform arrays of numbers and strings. But the most important use of map — especially once you get to the browser and React — is turning an array of objects into something you can display.
Think about any website you've used: a list of search results, a product grid, a social media feed. All of it is the same pattern: take an array of data objects, map over them, and produce something for each one.
You know HTML. So instead of producing plain strings, you can have map produce HTML markup:
const movies = [
{ title: "Inception", genre: "Sci-Fi", rating: 9.0 },
{ title: "Frozen", genre: "Animation", rating: 7.5 },
{ title: "Parasite", genre: "Thriller", rating: 8.6 },
];
const movieCards = movies.map(
(movie) => `<li>${movie.title} (${movie.genre}) — ${movie.rating}</li>`
);
console.log(movieCards);
// [
// "<li>Inception (Sci-Fi) — 9</li>",
// "<li>Frozen (Animation) — 7.5</li>",
// "<li>Parasite (Thriller) — 8.6</li>",
// ]
Your JavaScript is writing HTML for you — one <li> per movie, generated from real data. This is the core idea behind reusable templates and components. Instead of copy-pasting the same HTML markup for every item, you define it once inside the map callback and let the data drive the output.
To turn that array of strings into one big string you could actually drop into a page, use .join():
const movieList = movieCards.join("");
console.log(movieList);
// "<li>Inception (Sci-Fi) — 9</li><li>Frozen (Animation) — 7.5</li><li>Parasite (Thriller) — 8.6</li>"
.join("") stitches the array items together into a single string — the "" means no separator between them. Strings have built-in methods just like arrays do. You'll see more of them when we get to the DOM.
When you get to React, map does the exact same job — except instead of returning HTML strings, you'll return UI components. The pattern is identical.
Practice 3
const students = [
{ name: "Alice", grade: 88, passing: true },
{ name: "Bob", grade: 61, passing: false },
{ name: "Carol", grade: 95, passing: true },
{ name: "Dave", grade: 70, passing: true },
];
- Use
filterto get only passing students. - Chain
mapto turn each passing student into an<li>like<li>Alice — 88</li>.
Hint
Filter first, then chain map. Each item in the filtered result is a student object — use dot notation to access name and grade inside your template literal.
Solution
const passingStudents = students
.filter((student) => student.passing)
.map((student) => `<li>${student.name} — ${student.grade}</li>`);
console.log(passingStudents);
// ["<li>Alice — 88</li>", "<li>Carol — 95</li>", "<li>Dave — 70</li>"]
sort: Reorder an Array
sort reorders the items in an array. Unlike map and filter, sort mutates the original array — it doesn't create a new one.
const scores = [85, 92, 61, 78];
scores.sort((a, b) => a - b); // low to high
console.log(scores); // [61, 78, 85, 92] — original array changed
The callback receives two items (a and b) and decides their order:
- Return a negative number →
acomes first - Return a positive number →
bcomes first a - b→ ascending (low to high)b - a→ descending (high to low)
If you want to sort without touching the original, spread a copy first:
const sorted = [...scores].sort((a, b) => a - b);
That's the immutable approach — make a copy, sort the copy.
Note: We have learned about using meaningful variable names, but a and b are a standard convention for sort comparisons — one of those exceptions, like i for index in a loop, where the short names are universally understood and expected. Just know that single-letter names are the exception, not the rule.
Honorable Mentions
These follow the same callback pattern you already know. You don't need to memorize them — just recognize them when you see them.
some — returns true if at least one item passes:
const students = [
{ name: "Alice", grade: 88 },
{ name: "Bob", grade: 95 },
];
const hasFailingStudent = students.some((student) => student.grade < 70);
console.log(hasFailingStudent); // false
every — returns true only if all items pass:
const allPassing = students.every((student) => student.grade >= 70);
console.log(allPassing); // true
Checkpoint
Write your answers in handwritten notes ✍️.
- What two parameters does a
reducecallback receive? - What does the initial value in
reducedo? Why should you always provide one? mapandfilterreturn new arrays. What doesreducereturn?- Why should you spread a copy before sorting if you don't want to mutate the original?
Wrap-Up
Key Takeaways
reducecollapses an array to a single value — the callback receives an accumulator and the current item; always initialize the accumulatormapis the core tool for turning data into display — you'll use this pattern constantly in the browser and in Reactsortmutates — spread a copy first if immutability matterssome/everyreturn a boolean — useful for quick checks on a whole array