Once you are comfortable with loops, most of the ones you write turn out to be the same four shapes:
- Change every item into something else. Prices to prices with tax.
- Keep some items. Orders that are unpaid.
- Reduce many items to one value. A total, a count, a maximum.
- Find one item. The user with this id.
JavaScript has a method for each, and using them says what you meant rather than how you did it.
```
// The loop
const names = [];
for (const user of users) {
names.push(user.name);
}
// The transformation
const names = users.map((user) => user.name);
```
The second version is shorter, but the real gain is that map announces "same number of items, each changed". A reader knows that before reading the body.
The four
| Shape | Method | Returns |
|---|---|---|
| Change each | map | A new array, same length |
| Keep some | filter | A new array, shorter or equal |
| Combine to one | reduce | Any single value |
| Find one | find | The item, or undefined |
Plus two that answer yes or no: some (is any true?) and every (are all true?).
They do not change the original
map and filter return new arrays and leave the input alone. That matters more than it sounds: functions that do not modify their inputs are much easier to reason about, because calling one cannot break something elsewhere.
```
const prices = [10, 20];
const withTax = prices.map((p) => p * 1.2);
// prices is still [10, 20]
```
Chaining
Because each returns an array, they compose:
```
const total = orders
.filter((order) => !order.refunded)
.map((order) => order.amount)
.reduce((sum, amount) => sum + amount, 0);
```
That reads as a sentence: drop the refunds, take the amounts, add them up.
Make the lesson usable
A transformation should answer three questions: what shape comes in, what shape goes out, and what rule connects them. Keeping those answers explicit makes map, filter, reduce, grouping, and sorting easier to choose and accidental mutation easier to spot.
Design a transformation pipeline
- Write a three-record input array, including one awkward record with a missing or zero value.
- Describe the required output without naming a JavaScript method.
- Give each transformation one job and inspect the intermediate shape before adding the next step.
- Verify the original input remains unchanged unless mutation was intentional.
- Decide whether the awkward record should be rejected, defaulted, or preserved for review.
Check your understanding
01When is map the natural choice?
When each input item should produce one corresponding output item.
02When is filter the natural choice?
When the output keeps only items satisfying a condition.
03Why inspect intermediate values?
They reveal the first transformation that changed the data incorrectly.