56. Iterator::map_while — Take While Transforming
Need to take elements from an iterator while a condition holds and transform them at the same time? map_while does both in one step — no awkward take_while + map chains needed.
The Problem
Imagine you’re parsing leading digits from a string. With take_while and map, you’d write something like this:
| |
This works, but the condition and the transformation are split across two combinators. The unwrap() in map is also a code smell — you know the char is a digit because take_while checked, but the compiler doesn’t.
The Solution
map_while combines both steps. Your closure returns Some(value) to keep going or None to stop:
| |
char::to_digit already returns Option<u32> — it’s Some(n) for digits and None otherwise. That’s a perfect fit for map_while. No separate condition, no unwrap.
A More Practical Example
Parse key-value config lines until you hit a blank line:
| |
When split_once('=') hits the empty line "", it returns None — and the iterator stops. Everything after the blank line is skipped, no extra logic required.
map_while vs take_while + map
The key difference: map_while fuses the predicate and the transformation into one closure, which means:
- No redundant checks — you don’t test a condition in
take_whileand then repeat similar logic inmap. - No unwrap — since the closure returns
Option, you never need tounwrapinside a subsequentmap. - Cleaner intent — one combinator says “transform elements until you can’t.”
Reach for map_while whenever your stopping condition and your transformation are two sides of the same coin.