Hi, I am new to Rust and as I have a Python background, Rust gives me hard time often.
I desperately looking for help with iterating over a vector of results as I cannot wrap my head around it. I read the Rust Book, googled the problem, searched on forum and youtube, but still cannot find the answer. I spent three evenings on the problem, came up with working solutions, but they do not look idiomatic/good-practice (I have no Rust experience) and I cannot find a good example of solving my problem. Moreover, I found the solution more as a trial-error way, thus, I do not really understand why these solution works and not the other I tried.
Problem statement:
I am learning by doing a project and I am using an external function that returns Vec<Result<(Vec<u8>, u8)>, _>
I want to iterate over it and filter based on the second value of each tuple.
Example 1
Here is a simpler toy example without tuples.
let vec = vec![Ok(0), Ok(1), Err(2)];
let res: Vec<_> = vec.into_iter().filter(|t| {
match t {
Ok(val) => *val >= 1,
Err(_) => false
}
}).collect();
println!("{:?}", res);
// Returns: [Ok(1)] // Corect
Questions:
- Is using
match
in closure a good practice? Can I filter the vector elements based on their inner value (insideResult
) in a simpler and more elegant way?
I tried different approaches, but most of the time the compiler complains that the1
should be of typeResult
noti32
. I would like to avoid using anyunwrap
or other unsafe methods.
Example 2
Here same example but now the elements are tuples as in my project problem.
let vec = vec![Ok((0,1)), Ok((1,2)), Err((2,3))];
let res: Vec<_> = vec.into_iter().filter(|t| {
let x = t.map(|(x1,x2)| x2);
match x {
Ok(val) => val >= 1,
Err(_) => false
}
}).collect();
println!("{:?}", res);
// Returns: [Ok((0,1)), Ok((1,2))] // Corect
Questions:
- If the
Result
contains a tuple, how to 'deconstruct'Result
in Example 2 in idiomatic way, so that I can use the tuple inner elements for filtering? I don't like thefilter
part I came up with and thet.map()
as it seems too complicated and 'spaghetti code' like.
TLDR
What I want to achieve?
- Iterate over a vector where each element is of type
Result<(_, _), _>
. - Filter the vector based on the second element of each tuple (see Example 2)
- I am not interested in Errors, just omit them in the final collected results.
-
res
can be of typeVec<_>
orResult<Vec<_>, _>
for now I do not care (or should I?).
My main problems:
- If each element of a vector is a
Result
how to filter them based on the inner values? What is the more idiomatic (good-practice) way of doing so, but without using some unsafe methods such asunwrap
etc? - What is the best practice to get to the inner values of tuples wrapped in
Results
and then filter based on some element of each tuple? (Example 2)
I appreciate any help, idiomatic/good-practice solutions or some resource where I can learn more (but I tried the Rust book already and Rust by Example )