Search code examples
rustidioms

Idiomatic way to count occurrences in a collection of Options


I want to count number of occurrences of a value in a collection of Options.

let v = vec![Some(1), Some(1), Some(3), None];
v.iter()
 .filter(|Some(x)| x == &1)
 .count();

Doing this gives refutable pattern not covered error which makes sense.

I got around this by doing

v.iter()
 .filter(|x| x.is_some() && x.unwrap() == &1)
 .count()

What's the idiomatic way to do this in rust?


Solution

  • You can use flatten to get rid of None and unwrap the Some(...) values.

    Code:

    let one_count = v.iter().flatten().filter(|x| **x == 1).count();
    

    To count None s you can simply use this:

    let none_count = v.len() - v.iter().flatten().count();
    

    Playground

    Why Flatten works for Options ?

    From @E_net4 's comment: Since Option implements IntoIterator it can behave like an empty iterator or iterator with a single element .

    • Empty Iterator for None
    • Iterator with single element for Some(...)