Loops

Apply refactorings
Symptom

Imperative for/while loops obscuring what the loop is producing — filter, map, reduce mixed together by hand.

Goal

The transformation reads as a sequence of named operations: filter, map, reduce.

Smellier version

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

Fresher version

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

Reader must mentally execute the loop to learn the result; off-by-one errors and accumulator bugs hide in the body.

Tradeoff

Pipelines (filter/map/reduce) introduce per-element function-call overhead and force the reader to track intermediate collection shapes; in tight loops the overhead is real.

Relief

Intent reads in domain language; bugs concentrate on individual steps that are independently testable.

Trap

Forcing every loop into a pipeline — including loops with early-exit, accumulator-with-side-effects, or genuinely sequential dependencies — produces .reduce() bodies that are harder to read than the original.