Iterators

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"]