Skip to content

map + filter with unwrap on options and results #15026

@nyurik

Description

@nyurik
Contributor

What it does

Given a sequence of Option types like &[Option<T>], users sometimes tend to iterate with filter + map(unwrap) sequence. Instead, they should use .flatten().map() without the unwrap.

Other cases:

  • sequence of Results
  • usage of other "unwrapping" functions like unwrap_or_default, expect, etc

Advantage

  • Faster and cleaner code without panic

Drawbacks

No response

Example

pub fn filter_and_map_options(values: &[Option<i32>]) -> String {
    values
        .iter()
        .filter(|v| v.is_some())
        .map(|v| v.unwrap().to_string())
        .collect::<String>()
}

Could be written as:

pub fn filter_and_map_options(values: &[Option<i32>]) -> String {
    values
        .iter()
        .flatten()
        .map(|v| v.to_string())
        .collect::<String>()
}

Activity

matthiaskrgr

matthiaskrgr commented on Jun 9, 2025

@matthiaskrgr
Member

could also use flatten() I think?

pub fn filter_and_map_options(values: &[Option<&i32>]) -> String {
    values
        .iter()
        .flatten()
        .map(|x| x.to_string())
        .collect::<String>()
}
nyurik

nyurik commented on Jun 10, 2025

@nyurik
ContributorAuthor

oh, good idea, thanks! I didn't even realize this. Also, I wounder if we should have more lints like these?

  • iter.filter(|v| v.is_some()).map(...) - always suggest iter.flatten(), even if we cannot detect if there is an unwrap - simply because the chances of user wanting to preserve a sequence of Options are low. Sadly, this is less than certain.
  • same, but if map clearly unwraps the value - high confidence iter.flatten(), with the result probably compiling ok
  • iter.filter_map(|v| v.map(|v| ...)) - treat it the same as above
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-lintArea: New lints

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @matthiaskrgr@nyurik

        Issue actions

          map + filter with unwrap on options and results · Issue #15026 · rust-lang/rust-clippy