flatten()
The .flatten() adapter removes one level of nesting from an iterator whose items implement IntoIterator (such as nested collections Vec<Vec<T>>, arrays [T; N], Option<T>, or Result<T, E>).
Signature
fn flatten(self) -> Flatten<Self>
where
Self: Sized,
Self::Item: IntoIterator,
The output iterator Flatten<Self> has type Item = <Self::Item as IntoIterator>::Item.
Flattening Nested Collections
When iterating over a sequence of slices, vectors, or fixed-size arrays, .flatten() yields all inner elements sequentially:
fn main() {
let matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
let row_major: Vec<i32> = matrix.into_iter().flatten().collect();
println!("Flattened matrix: {row_major:?}");
}
Flattened matrix: [1, 2, 3, 4, 5, 6, 7, 8, 9]
Note that .flatten() only removes one level of nesting per call; a 3D array [[[i32; 2]; 2]; 2] requires .flatten().flatten() to yield i32.
Flattening Option<T> and Result<T, E>
Because both Option<T> and Result<T, E> implement IntoIterator (yielding 1 item for Some(v) / Ok(v) and 0 items for None / Err(_)), calling .flatten() on an iterator of Option<T> or Result<T, E> unwraps all present/successful values and discards None and Err:
Outer Self::Item |
<Self::Item as IntoIterator>::Item |
Effect of .flatten() |
|---|---|---|
Vec<T> / [T; N] |
T |
Concatenates all inner elements |
Option<T> |
T |
Keeps x from Some(x), skips None |
Result<T, E> |
T |
Keeps x from Ok(x), silently discards Err(e) |
fn main() {
let maybe_ports = [Some(80_u16), None, Some(443), None, Some(8080)];
let results: [Result<&str, &str>; 3] = [Ok("ok-1"), Err("timeout"), Ok("ok-2")];
let ports: Vec<u16> = maybe_ports.into_iter().flatten().collect();
let successes: Vec<&str> = results.into_iter().flatten().collect();
println!("Ports: {ports:?}");
println!("Successes: {successes:?}");
}
Ports: [80, 443, 8080]
Successes: ["ok-1", "ok-2"]