117. Iterator::step_by — Every Nth Element Without filter + enumerate
Want every 3rd value from a series? The reflex is enumerate().filter(|(i, _)| i % 3 == 0) — three combinators, one modulo, and you’ve thrown away the indices anyway. step_by(3) does the same thing in one call.
The classic shape: keep every Nth item, drop the rest. Most people reach for enumerate plus a modulo filter:
| |
That works, but you’re indexing just to throw the index away, and the filter runs once per element even though the iterator already knows where to land.
Iterator::step_by(n) yields the first item, then advances by n - 1, repeating. Same result, no bookkeeping:
| |
The first element is always included — step_by(n) starts at index 0, then jumps. If you want to skip the first one, chain with skip:
| |
It composes nicely with ranges, which is where it really shines — multiples, downsampling, every-other-frame logic without writing the loop yourself:
| |
One footgun: step_by(0) panics. The step has to be at least 1, which makes sense — you can’t “advance by zero” and make progress — but it’s a runtime panic, not a compile error, so don’t pass a step you computed at runtime without checking.
| |
Reach for step_by whenever you’d otherwise write enumerate().filter(|(i, _)| i % n == 0) — same behavior, half the code, and the iterator can actually skip elements instead of inspecting every one.