Camden Narzt
Camden Narzt

Reputation: 2013

How can I return a subset of a Vec?

I'm trying to avoid copying data as the memory use of this program has to be kept low.

I've seen that you can do something like:

fn subset<'a>(csv: &Vec<&'a Vec<bool>>, indices: &Vec<usize>) -> Vec<&'a Vec<bool>> {
    indices.iter().map(|&i| &csv[i]).collect();
}

But my data source is actually a &Vec<Vec<bool>> not a &Vec<&Vec<bool>> and 'a on it's own doesn't work.

Upvotes: 0

Views: 629

Answers (1)

Matthieu M.
Matthieu M.

Reputation: 300409

Your 'a is simply misplaced.

A lifetime is always used in conjunction with a reference, so if you have a &Vec<Vec<bool>> then the lifetime 'a comes right after the &. You do not need, and should not, sprinkle & nilly-willy as there is a very clear difference between something that you own (i32) and something you refer to (&i32).

Thus, the correct version of your function simply is:

fn subset<'a>(csv: &'a Vec<Vec<bool>>, indices: &Vec<usize>) -> Vec<&'a Vec<bool>> {
    indices.iter().map(|&i|&csv[i]).collect()
}

Note: I removed the semi-colon after collect, as you want to return the value of that expression.

And we can use this function:

fn main() {
    let vec = vec!(
        vec!(false, false, false),
        vec!(false, false, true ),
        vec!(false, true , true ),
        vec!(false, true , false),
        vec!(true , true , false),
        vec!(true , true , true ),
        vec!(true , false, true ),
        vec!(true , false, false)
    );

    let indices = vec!(1, 3, 5, 7);

    let sub = subset(&vec, &indices);

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

Which produces:

[[false, false, true], [false, true, false], [true, true, true], [true, false, false]]

Upvotes: 2

Related Questions