Get multiple elements from vector at once


#1

What would be the fastest way to get the element of a vector using a another vector representing the indexes ?

Ie

let indexes = [1, 3, 4];
let values = ["data1", "data2", "data3", "data4". "data5"];

Values will be changing quickly but not indexes.

I have looked into Vec.retain but not sure how to use indexes.

Or would I be forced to use a loop ?

Thanks


#2

Would this here solve your problem?

https://play.rust-lang.org/?gist=0182b215775a54149e58a87a3350f9fb&version=stable&backtrace=0

fn main() {
    let indexes = [1usize, 3, 4];
    let values = ["data1", "data2", "data3", "data4", "data5"];
    
    let borrowed = indexes.iter().map( |i| values[*i] ).collect::<Vec<_>>();
    println!("{:?}", borrowed);
}

#3

No need to concern yourself about that, as long your algorithms are fast, this is Rust. You can easily have an iterator over indexes that maps over values (for each element in indexes, it retrieves a value).

fn main() {
    let indexes = [1, 3, 4];
    let values = ["data1", "data2", "data3", "data4", "data5"];
    for value in indexes.iter().map(|&index| values[index]) {
        println!("{}", value);
    }
}

It’s somewhat trickier if you need to take ownership of non-Copy values. Assumming indexes are sorted with no duplicates, you can do this.

fn retain_indexes<T, I>(values: &mut Vec<T>, indexes: I)
    where I: IntoIterator<Item = usize>
{
    // Precondition: Sorted indexes, no duplicates
    let len = values.len();
    let mut deleted = 0;
    let mut indexes = indexes.into_iter().peekable();
    for i in 0..len {
        if indexes.peek() == Some(&i) {
            indexes.next();
            values.swap(i - deleted, i);
        } else {
            deleted += 1;
        }
    }
    values.truncate(len - deleted);
}

fn main() {
    let indexes = [1, 3, 4];
    let mut values = vec!["data1", "data2", "data3", "data4", "data5"];

    retain_indexes(&mut values, indexes.iter().cloned());

    println!("{:?}", values);
}

#4

Yes thank you. Thats’ great.

I think I was messing it up by iterating values.