rustoption-typerayon

Rust Rayon collect Options into Vector


I am trying to use rayon par_iter with map (and enumerate). However, the closure returns an Option. Is there a way to collect the Some value of that option while filtering out Nones? What I do currently is

let par_iter = seqs.into_par_iter().enumerate().map(|(i, d)| -> Option<(String, usize)> {
    let mut rng = thread_rng();
    let is_ok = somefunc(d);
    if is_ok {
        return Some((d, i))
    } else {
        return None
    }
});

let res = par_iter.collect::<Vec<Option<(String, usize)>>>();

let mut output: Vec<(String, usize)> = Vec::new();
for opt in res {
    if let Some(d) = opt {
        output.push(d);
    }
}

where seqs is Vec<String>. Is there a less verbose or more typical way of doing this?


Solution

  • Easy:

    let res = seqs
        .into_par_iter()
        .enumerate()
        .map(|(i, d)| -> Option<(String, usize)> {
            let mut rng = thread_rng();
            let is_ok = somefunc(d);
            if is_ok {
                return Some((d, i));
            } else {
                return None;
            }
        })
        .filter_map(std::convert::identity)
        .collect::<Vec<(String, usize)>>();
    

    Or:

    let res = seqs
        .into_par_iter()
        .enumerate()
        .map(|(i, d)| -> Option<(String, usize)> {
            let mut rng = thread_rng();
            let is_ok = somefunc(d);
            if is_ok {
                return Some((d, i));
            } else {
                return None;
            }
        })
        .flatten()
        .collect::<Vec<(String, usize)>>();
    

    From benchmarking using criterion, the filter_map() version is 10x faster, so you should probably use it.