0

Given two same length Vec<u8>, trying to select an element from each index with a given probability p: f32, as follows,

fn select(xs: &Vec<u8>, ys: &Vec<u8>, p: f32) -> Vec<u8> {
    let mut rng = rand::thread_rng();
    xs
        .iter()
        .zip(ys.iter())
        .map(|(a, b)| if rng.gen_range(0.0..1.0) < p { a } else { b })
        .collect()
}

However,

value of type `Vec<u8>` cannot be built from `std::iter::Iterator<Item=&u8>`

How to collect an iterator into a new vector?

1 Answer 1

3

Just copy your values for example by dereferencing * or using & in the pattern1:

use rand::Rng;
fn shuffle(xs: &[u8], ys: &[u8], p: f32) -> Vec<u8> {
    let mut rng = rand::thread_rng();
    std::iter::zip(xs, ys)
        .map(|(x, &y)| if rng.gen_range(0.0..1.0) < p { *x } else { y })
        .collect()
}

For most FromIterator implementations the item iterated over has to be the same as the one that ends up in the collection, but you're iterating over &u8 and want to end up with just u8 in the collection.

Other changes:

  • &Vec<u8>&[u8] as it's more general,
  • xs.iter().zip(ys.iter()) as that's really not very readable, if you zip more than once use std::iter and iter::zip(xs, ys) else just use that function directly
  • use x and y for values of xs and ys respectively

1) Obviously in your code just stick to one of the ways, just showing both posibilities here for illustration.

Sign up to request clarification or add additional context in comments.

1 Comment

Nothing wrong with this answer, but I believe another option to mention might be .copied() to convert from iterator of &T (where T: Copy) to iterator of T ahead of time. Not a big difference either way, but it's slightly more explicit. For something that doesn't implement Copy, but does implement Clone, there's .cloned(), which is even more useful to my mind (since adding .clone() calls within the callback clutters things, so it's nice to get that out of the way ahead of time).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.