Idiomatic way to only get insides of `Some` from a vector of options?

Viewed 572

I'm learning Rust and am trying to get used to working with Results and Options. Given a vector of either. If i only want the results that did not err (or aren't none for Option), is there a more graceful way of doing this than below or is this about the amount of boilerplate i'd have to usually write?

I realize there are a lot more granular that one can do in map like unwrap_or_else and partition good results away from bad.


    let optvec   = vec![Some(1), None, Some(4), None];
    let filtered = optvec.iter()
    .filter(|q| q.is_some())
    .map(|q| q.unwrap())
    .collect::<Vec<i32>>();

2 Answers

You can use filter_map it only returns the Somes not the Nones.

let optvec   = vec![Some(1), None, Some(4), None];
let filtered: Vec<i32> = optvec.iter().filter_map(|f| *f).collect();
println!("{:?}", filtered);
>>> [1, 4]

In your case since you are not doing any mapping, I would suggest using flattening instead of filter_maping. Which in my opinion is much clearer and more self explanatory.

    let optvec = vec![Some(1), None, Some(4), None];
    let filtered: Vec<i32> = optvec.iter().flatten().cloned().collect();
    assert_eq!(filtered, &[1, 4]);
Related