If let expression within .iter().any

Advertisements

Here’s some code I have:

fn my_func(i: i32) -> Result<i32, String> {
    match i {
        42 => Ok(113),
        _ => Err("Can only use 42".to_string())
    }
}

fn main() {
    let myvec = [1, 2, 42];
    if myvec.iter().any(|i| my_func(*i).is_ok()) {
        println!("something was ok");
    } else {
        println!("nothing was ok");
    }
}

Instead of println!("something was ok");, I’d like to print which element was OK.

But if I assign to a variable within any, then it won’t be visible within the println! statement.

Desired output, in this case, would be:

something was ok: 42

>Solution :

Iterator::any isn’t capable of returning a value. It only returns true or false. The variant of any that does return a value is called Iterator::find_map.

Applies function to the elements of iterator and returns the first non-none result.

iter.find_map(f) is equivalent to iter.filter_map(f).next().

Option<B> is really just a Boolean with extra information in the "true" case, so we’ll use that extra information to return a useful value.

let myvec = [1, 2, 42];
    if let Some(value) = myvec.iter().find_map(|i| my_func(*i).ok()) {
        println!("something was ok: {}", value);
    } else {
        println!("nothing was ok");
    }
}

Result::ok takes a Result and maps it to an Option. Ok becomes Some and any Err becomes None (with the actual error information discarded).

Leave a ReplyCancel reply