Iterators

filter_map()

The .filter_map() adapter combines filtering and mapping into a single step by applying an FnMut(Self::Item) -> Option<B> closure to each element, unwrapping and yielding b for every Some(b) and discarding every None.

Signature

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>
where
    Self: Sized,
    F: FnMut(Self::Item) -> Option<B>,
Source: [ "42",      "bad",   "108"     ]
            │          │        │   .filter_map(|s| s.parse::<i32>().ok())
            ▼          ▼        ▼
Option:   Some(42)   None     Some(108)
            │          ✕        │
            ▼                   ▼
Output: [  42,                 108      ]

Parsing and Extracting Valid Items with .filter_map()

Whenever a transformation naturally returns an Option<B> (or a Result<B, E> converted via .ok()), .filter_map() avoids either parsing twice (.filter(|s| s.parse().is_ok()).map(|s| s.parse().unwrap())) or chaining .map(...).filter(Option::is_some).map(Option::unwrap):

fn main() {
    let raw_inputs = ["25", "N/A", "100", "", "-7", "invalid"];

    let numbers: Vec<i32> = raw_inputs
        .into_iter()
        .filter_map(|s| s.parse::<i32>().ok())
        .collect();

    println!("Parsed integers: {numbers:?}");
}
Parsed integers: [25, 100, -7]

Pattern Matching Inside .filter_map()

.filter_map() is also ideal for extracting a specific enum variant from a heterogeneous sequence:

#[derive(Debug)]
enum Event {
    Heartbeat,
    Message { sender: &'static str, body: &'static str },
    Disconnect,
}

fn main() {
    let stream = [
        Event::Heartbeat,
        Event::Message { sender: "alice", body: "hello" },
        Event::Disconnect,
        Event::Message { sender: "bob", body: "ack" },
    ];

    let chat_lines: Vec<String> = stream
        .iter()
        .filter_map(|event| match event {
            Event::Message { sender, body } => Some(format!("{sender}: {body}")),
            _ => None,
        })
        .collect();

    println!("{chat_lines:?}");
}
["alice: hello", "bob: ack"]

.filter_map(f) vs. .filter(p).map(m)

Scenario Prefer
Condition and transformation are intertwined (e.g., str::parse, checked_add, enum variant extraction) .filter_map(f)
Simple boolean check followed by an unrelated transformation, where filter rejects most items cheaply before an expensive map .filter(p).map(m)
Iterator already yields Option<T> and you only want to unwrap Some(T) .flatten()