map()
The .map() adapter transforms each element of an iterator by applying an FnMut(Self::Item) -> B closure, returning a lazy std::iter::Map<Self, F> iterator that yields the transformed values of type B.
Signature
fn map<B, F>(self, f: F) -> Map<Self, F>
where
Self: Sized,
F: FnMut(Self::Item) -> B,
Each time .next() is called on Map<Self, F>, it pulls one item from the underlying iterator:
- If the inner iterator returns
Some(x),MapreturnsSome(f(x)). - If the inner iterator returns
None,MapreturnsNone.
Source: [ 1, 2, 3 ]
│ │ │ .map(|x| x * 10)
▼ ▼ ▼
Output: [ 10, 20, 30 ]
Transforming Values and Changing Types
The output type B does not need to match the input type Self::Item:
fn main() {
let radii = [1.0_f64, 2.5, 4.0];
// Transforms `f64` -> formatted `String`:
let labels: Vec<String> = radii
.into_iter()
.map(|r| {
let area = std::f64::consts::PI * r * r;
format!("r={r:.1} -> area={area:.2}")
})
.collect();
for label in &labels {
println!("{label}");
}
}
r=1.0 -> area=3.14
r=2.5 -> area=19.63
r=4.0 -> area=50.27
Passing Named Functions or Tuple Struct Constructors to .map()
Because named functions and tuple struct / enum variant constructors (Some, Ok, Bytes) implement Fn(A) -> B, you can pass them directly to .map() without wrapping them in a closure:
#[derive(Debug)]
struct UserId(u64);
fn main() {
let raw_ids = [101_u64, 102, 103];
let words = [" alpha ", " beta "];
// 1. Passing tuple-struct constructor `UserId` directly:
let users: Vec<UserId> = raw_ids.into_iter().map(UserId).collect();
// 2. Passing method path `str::trim` directly:
let trimmed: Vec<&str> = words.into_iter().map(str::trim).collect();
println!("Users: {users:?}");
println!("Trimmed: {trimmed:?}");
}
Users: [UserId(101), UserId(102), UserId(103)]
Trimmed: ["alpha", "beta"]
Preserving ExactSizeIterator and DoubleEndedIterator
Because .map() is a strict 1-to-1 transformation (1 input item produces 1 output item), Map<I, F> implements ExactSizeIterator whenever I: ExactSizeIterator and DoubleEndedIterator whenever I: DoubleEndedIterator. This allows .collect::<Vec<_>>() after .map() to pre-allocate the exact output capacity in a single heap allocation.