urschrei
urschrei

Reputation: 26879

Is there a fast way to check a Vec for an error result?

I'm using Rayon to iterate over a vector, producing a Vec of results:

let coordinates = &[[38.5, -120.2], [40.7, -120.95], [430.252, -126.453]]
let mut res = vec![];
coordinates
    .par_iter()
    .map(|pair| {
        match (check(&pair[0]), check(&pair[1])) {
            (Ok(v1), Ok(v2)) => Ok([v1, v2]),
            (Err(v), _) => Err(v),
            (_, Err(v)) => Err(v),
        }
    })
    .collect_into(&mut res);

I'd like to check res for any error values, convert them into String and return them using try!()

This works, but it's slow and inefficient, considering that I'm allocating a new vector just to aggregate my results or pull out an error:

let errcheck: Result<Vec<_>, f64> = res.iter().map(|elem| *elem).collect();
try!(errcheck.map_err(|e| format!("Error: {}", e).to_string()));

This problem appears to be Rayon-specific; if I use .iter(), I can collect directly into errcheck using collect() and map_err() in the match arms, which I can't seem to do using par_iter().

Is there a better way to do it?

Upvotes: 3

Views: 1079

Answers (1)

J.J. Hakala
J.J. Hakala

Reputation: 6214

If you need only the items that do not fulfil certain conditions, there is filter():

let bounds1 = (-90.0, 90.0);
let bounds2 = (-180.0, 180.0);
let (xmin, xmax) = bounds1;
let (ymin, ymax) = bounds2;

coordinates.par_iter().filter(|pair| {
    let x = pair[0];
    let y = pair[1];
    !((xmin <= x) && (x <= xmax) && (ymin <= y) && (y <= ymax))
}).for_each(|pair| {
    println!("Bad pair: {} {}", pair[0], pair[1]);
});

In other words, is map the right operation in the first place.

Upvotes: 3

Related Questions