Rewriting for loop using filter_map

I have got two Vecs a and b coming from another part of the program:

let mut a: Vec<(&mut X, bool)> = Vec::new(); //comes from somewhere else
let mut b: Vec<(Option<usize>, &mut X)> = Vec::new(); //comes from somewhere else

Furthermore, I have a for loop pushing some elements from b into a

for (count, x) in b {
        if let Some(0) = count {
            a.push((x, false));
        }
    }

I tried to rewrite this for loop using the filter_map function but failed to get it to work

a.extend(b.iter().filter_map(
    |(count, x)|{
        if let Some(0) = count {
            Some((x, false))
        }
        else {
            None
        }
    }
))

Could someone give me a hint?

Stab in dark :

a.extend(b.into_iter().filter_map(...))
           ^^^^

Post the error you're getting and possibly a reproducible playground.

1 Like

Link to the playground: playground

The error indicates that the types don’t match. I tried chaining it from Some((x, false)) to Some((*x, false)) but that did not work either

You can't do this as is:

b contains mutable references to instances of X, and pushing those into a and trying to keep them as mutable references would create two separate mutable references to the same value, which is not allowed.

Or, in more empirical code:

b.iter()

Returns &T items, from which one cannot acquire &mut Anything,

b.iter_mut()

Returns &mut T items, from which one can acquire mutable references, however you cannot use b anymore after that (since now the lifetime of the mutable references in a are tied to a mutable borrow of b).

b.into_iter()

Is the same idea as iter_mut().


Note that variance rules would come into consideration should you choose iter_mut() or into_iter().

1 Like

You can do it if you consume b... as your original for loop did. This is what @jRimbault was suggesting.

2 Likes