Replace Loop with Pipeline

Removes smells
Symptom

Imperative for/while loops where filter, map, and reduce concerns are mixed by hand — the reader must mentally execute the body to learn what's being produced.

Goal

Filter / map / reduce expresses the transformation as a sequence of named operations; intent reads in domain language.

Before the refactoring

const seniors = [];
for (const u of users) {
if (u.age >= 65) seniors.push(u.name);
}

After the refactoring

const seniors = users
.filter(u => u.age >= 65)
.map(u => u.name);
Example source: Illustrative example written for this site, not a quotation from any source.
Pressure

Off-by-one errors and accumulator bugs hide in the body and only surface at test time; intent is buried under the mechanism.

Tradeoff

Pipelines add a tiny per-element function-call overhead — usually negligible, but profile if the call is on a hot path.

Relief

Off-by-one and accumulator bugs vanish; each step is independently testable.

Trap

Forcing every loop into a pipeline — including ones with early-exit, side-effect accumulators, or genuinely sequential dependencies — produces .reduce() bodies harder to read than the original.