Dataslope logoDataslope

Map, Filter, and Reduce

The three verbs that do 80% of modern JavaScript's work on arrays — and the mental shift behind them.

In the loops chapter we wrote out the "loop and accumulate" pattern by hand: walk an array, build up a result. JavaScript gives you three built-in methods — map, filter, and reduce — that express these patterns more clearly. Once they click, half the loops you would otherwise write disappear.

These three methods together are sometimes called the functional core of array processing.

The shift in mindset

A for loop says how to walk the array. The three methods say what to produce.

Loop says...Higher-order method says...
Step from index 0 to length-1"For each element..."
Push into a result array"Produce a new array of..."
Conditionally include"Keep only the ones where..."
Accumulate a single value"Combine all into..."

The pattern is: describe the transformation, not the mechanics.

map: transform every element

arr.map(fn) returns a new array of the same length, where each element is the result of fn applied to the original element.

Code Block
JavaScript ES2023+

Three things to notice:

  1. The original array is not modified.
  2. The result is always the same length.
  3. Each element is processed independently. The callback can't see the other elements.

If you need to skip elements, map is the wrong tool. That's what filter is for.

filter: keep only the elements that pass a test

arr.filter(fn) returns a new array containing only the elements for which fn returns a truthy value.

Code Block
JavaScript ES2023+

Notice the last example: Boolean is itself a function, and filter(Boolean) removes every falsy value in one stroke. Tiny idioms like this make functional code remarkably compact.

reduce: collapse the array into a single value

reduce is the most general of the three. It walks the array, maintaining an "accumulator", and produces a single final value.

arr.reduce(
  (accumulator, currentValue) => newAccumulator,
  initialAccumulator,
);
Code Block
JavaScript ES2023+

reduce is very general. Anything you can do with a manual "start with X, walk the array, update X, return X" loop, you can do with reduce. In fact, map and filter are themselves just special cases of reduce.

A common piece of advice: don't reach for reduce first. It can do anything, but its generality makes it harder to read than map or filter. Reach for it when you genuinely need to fold the array into a non-list result.

Composing the three

The real power of these methods is chaining. Each one returns a new array, so you can apply the next one immediately.

Code Block
JavaScript ES2023+

Read the first chain top-to-bottom. It says, in plain English: "take the orders, keep the paid ones, get each amount, add them all up." That readability — the way each step describes a small, clear transformation — is the whole point.

Other useful array methods

A few more that follow the same functional spirit:

Code Block
JavaScript ES2023+

some and every are particularly worth remembering — they often replace a hand-rolled loop with an early return true.

Data flow visualised

A chain of .filter().map().reduce() is a small data pipeline. Each step takes the previous output as input.

Each arrow carries a value (in this case, mostly arrays). Drawing a tiny pipeline like this on paper is a great way to plan transformations before writing code.

Performance notes (lightly)

Methods chained one after another walk the array multiple times. For small data this is fine; for arrays of millions of elements you might prefer a single hand-written loop or a streaming approach. For everyday programming, prefer the readable version — modern engines are fast, and clarity is more valuable than micro-optimisation.

A multi-file pipeline

Real-world programs build pipelines that span multiple modules: one module owns the transformations, another assembles them.

Code Block
JavaScript ES2023+

Challenge

Challenge
JavaScript ES2023+
Pipeline practice

Given an array of products, each shaped like { name, price, inStock }, write a function affordableInStock(products, maxPrice) that returns an array of names of products that are in stock AND have a price less than or equal to maxPrice, sorted alphabetically.

Use .filter, .map, and .sort() — not a hand-written for loop.

Examples:

  • For [{name:"A", price:5, inStock:true}, {name:"B", price:20, inStock:true}, {name:"C", price:3, inStock:false}] with maxPrice=10, return ["A"].
  • For the same input with maxPrice=100, return ["A","B"].

QuestionSelect one

Which of these is the cleanest expression of "give me a new array where each user's name is uppercased"?

A for loop that pushes into a new array

A for...of loop with manual indexing

users.map((u) => ({ ...u, name: u.name.toUpperCase() }))

A while loop that builds a new array index-by-index

On this page