पाठ 9 / 25
map, filter and reduce
Replacing loops with transformations, and when not to.
Three building blocks
map transforms every element and keeps the length; filter keeps elements that satisfy a predicate; reduce folds a collection into a single value using an accumulator. Together they express most loops as a pipeline of named intentions, and none of them mutate the source array. Python offers map, filter, functools.reduce and, more idiomatically, comprehensions. A plain loop is still clearer when you need early exit, complex state across iterations, or when a reduce callback grows long and hard to read.
A loop rewritten as a pipeline
Total revenue from paid orders, in TypeScript and Python.
type Order = { status: 'paid' | 'pending'; lines: { qty: number; price: number }[] };
const revenue = (orders: Order[]): number =>
orders
.filter(o => o.status === 'paid')
.map(o => o.lines.reduce((sum, l) => sum + l.qty * l.price, 0))
.reduce((a, b) => a + b, 0);
// Grouping with reduce: still pure, but a loop may read better here
const countByStatus = (orders: Order[]) =>
orders.reduce<Record<string, number>>(
(acc, o) => ({ ...acc, [o.status]: (acc[o.status] ?? 0) + 1 }),
{},
);
// Note: spreading acc on every step copies it each time (quadratic for many keys).The Python equivalent
Python has map, filter and functools.reduce, but idiomatic Python usually prefers a generator expression: sum(l["qty"] * l["price"] for o in orders if o["status"] == "paid" for l in o["lines"]) expresses the same revenue calculation.
त्वरित जाँच: When is a plain loop often the better choice?
- Never; loops are forbidden in FP
- Whenever the array has more than ten elements
- When you need early exit or the reduce callback becomes hard to follow
- When you want to keep the source array unchanged
Answer
When you need early exit or the reduce callback becomes hard to follow — Readability decides; FP is a tool, not a rule.