Skip to content

Beginner · Arrays and objects · topic 17 of 61 · 30 min

Array methods: map, filter, reduce and friends

Explanation

Array methods replace most hand-written loops. map changes every item, filter keeps the items that pass a test, reduce combines all items into one value, and find, some and every search. Chaining them turns raw data into answers in a few readable lines.

Why use array methods?

You wrote loop patterns in module 2: the builder, the search, the accumulator. Array methods are those same patterns with a name. Instead of writing the loop, you say WHAT you want, and each method returns a result you can pass to the next one. This style is called declarative.

map: change every item

javascript
const pricesPaise = [19900, 4950, 120000];
const labels = pricesPaise.map((p) => `₹${(p / 100).toFixed(2)}`);
console.log(labels); // ['₹199.00', '₹49.50', '₹1200.00']
map always returns a new array of the SAME length.

filter: keep some items

javascript
const orders = [
  { id: 1, city: 'Pune', amount: 450 },
  { id: 2, city: 'Delhi', amount: 1200 },
  { id: 3, city: 'Pune', amount: 900 },
];
const pune = orders.filter((o) => o.city === 'Pune');
console.log(pune.map((o) => o.id)); // [1, 3]

reduce: combine into one value

reduce walks the array with an accumulator. Your function receives the accumulator so far and the current item, and returns the new accumulator. The second argument of reduce is the starting value.

javascript
const total = orders.reduce((sum, o) => sum + o.amount, 0);
console.log(total); // 2550

const byCity = orders.reduce((acc, o) => {
  acc[o.city] = (acc[o.city] ?? 0) + o.amount;
  return acc;
}, {});
console.log(byCity); // { Pune: 1350, Delhi: 1200 }
Careful: Always give reduce a starting value. Without it, reduce uses the first element as the start, which breaks when items are objects (you get "[object Object]450…") and throws a TypeError on an empty array.

Searching: find, findIndex, findLast, some, every

javascript
const big = orders.find((o) => o.amount > 1000);   // { id: 2, … } or undefined
const idx = orders.findIndex((o) => o.id === 3);    // 2 or -1
const anyDelhi = orders.some((o) => o.city === 'Delhi'); // true
const allPaid = orders.every((o) => o.amount > 0);  // true

Flattening: flat and flatMap

javascript
console.log([[1, 2], [3], [4, [5]]].flat());   // [1, 2, 3, 4, [5]]
console.log([[1, [2, [3]]]].flat(Infinity));     // [1, 2, 3]
const tags = ['red shirt', 'blue jeans'].flatMap((s) => s.split(' '));
console.log(tags); // ['red', 'shirt', 'blue', 'jeans']

sort needs a compare function

By default, sort converts items to strings and sorts them alphabetically. That is why [10, 9, 1].sort() gives [1, 10, 9]. For numbers pass (a, b) => a - b for ascending or (a, b) => b - a for descending. For text, use (a, b) => a.localeCompare(b).

Chaining

javascript
const report = orders
  .filter((o) => o.amount >= 500)
  .map((o) => `#${o.id} ${o.city}`)
  .join(', ');
console.log(report); // '#2 Delhi, #3 Pune'

Grouping: Object.groupBy

ES2024 added Object.groupBy(list, fn), which groups items by the key your function returns: Object.groupBy(orders, (o) => o.city) gives { Pune: [...], Delhi: [...] }. It is in all current browsers and Node; in older environments use the reduce version above.

Tip: Pick the method by the question you are asking: "transform each?" map. "Which ones?" filter. "One total?" reduce. "Is there any?" some. "First one?" find.

Need help?

Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.

Try:

Watch the lesson

Array methods: map, filter, reduce and friends · 1/7

map · filter · reduce

In this lesson you will process data with the most important array methods.

Prefer a video by a teacher? Find free videos on “javascript map filter reduce explained with examples” on YouTube ↗

In real life: Class results on a school portal

A school portal receives every student's marks. In three chained steps it keeps the students who passed, sorts them by marks, and builds the merit list text shown on the notice board.

javascript
const students = [
  { name: 'Asha', marks: 91 }, { name: 'Ravi', marks: 28 },
  { name: 'Meena', marks: 77 }, { name: 'Kabir', marks: 84 },
];
const merit = students
  .filter((s) => s.marks >= 35)
  .toSorted((a, b) => b.marks - a.marks)
  .map((s, i) => `${i + 1}. ${s.name} (${s.marks})`);
console.log(merit);
Prints ['1. Asha (91)', '2. Kabir (84)', '3. Meena (77)'].

Practice (0/4 done)

Task 1 · Code · Javascript

Write doubleAll(nums) that returns a new array with every number doubled, using map.

Task 2 · Code · Javascript

Write cartTotal(items) that returns the sum of price * qty for every item, using reduce. Items look like { name, price, qty }.

Task 3 · Code · Javascript

Write expensiveNames(products, limit) that returns the names of products whose price is above limit, sorted A to Z.

Task 4 · Code · Javascript

Write countByCity(orders) that returns an object with the number of orders per city, using reduce. countByCity([{ city: "Pune" }, { city: "Pune" }, { city: "Goa" }]) returns { Pune: 2, Goa: 1 }.

Quick quiz

Question 1

1.What does [10, 9, 1].sort() give?

Question 2

2.What does [1, 2, 3, 4].filter((n) => n % 2).length give?

Question 3

3.What does find return when nothing matches?

Question 4

4.What is [[1, 2], [3]].flat()?

Question 5

5.[].reduce((a, b) => a + b) with no starting value does what?

Read more (free)

Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.

What does [10, 9, 1].sort() give?

Answer: [1, 10, 9]

Without a compare function, items are compared as strings: "1" < "10" < "9".

What does [1, 2, 3, 4].filter((n) => n % 2).length give?

Answer: 2

n % 2 is 1 (truthy) for odd numbers: 1 and 3.

What does find return when nothing matches?

Answer: undefined

find returns undefined; findIndex returns -1.

What is [[1, 2], [3]].flat()?

Answer: [1, 2, 3]

flat removes one level of nesting by default.

[].reduce((a, b) => a + b) with no starting value does what?

Answer: Throws a TypeError

reduce of an empty array with no initial value throws a TypeError.

Which method does NOT change the original array?Related

Answer: toSorted()

toSorted returns a new sorted array. sort, reverse and splice all change the array they are called on.

From More array power

Which method returns a new array with only the items that pass a test?Related

Answer: filter

filter keeps the items for which the callback returns true.

From Arrays and array methods

Which operation turns List<Order> into Map<String, List<Order>>?Related

Answer: groupBy

groupBy collects items under each key.

From Collection operations

Why use break in a search loop?Related

Answer: To stop as soon as the item is found

Once found, looking further wastes time.

From Loop patterns that solve real problems

Pass the quiz (60% or more) or mark this topic as done when you are ready.

Your progress is saved on this device only.

Next steps

  1. 3 more topics in “Arrays and objects” before its exam: Objects: keys and values, Destructuring, spread and rest, References, copies and equality.
  2. Module 4 exam: Arrays and objects · 12 questions · 25 min, without help. 5 topics of this module still to finish first.
  3. Then the next module, Scope, this, prototypes and classes. 61 topics left in the course before the final exam.

← Previous: Arrays: lists of values