Preferred way of removing items from Vec


#1

Hi,

I have a Vec with a bunch of items. Each item has an id (which can be the same for several items) and want to remove the items. One obvious way would just be to iterate over the Vec and build a new one and just skip the items that shouldn’t be in there.

While this would work it also adds quite a bit of extra (de)allocations and memory shuffling so I wonder if there is some other way to do it?


#2

Is this enough?

https://doc.rust-lang.org/std/vec/struct.Vec.html#method.retain


#3

Behold:

fn main() {
    let mut v: Vec<_> = (0..20).collect();
    
    // Begone, filthy evens!
    // Begone but do not disturb the order!
    v.retain(|e| *e & 1 == 1);
    println!("{:?}", v);
    
    // Begone, filthy "divisible-by-three"s!
    // Begone with minimal shuffling!
    for i in (0..v.len()).rev() {
        if v[i] % 3 == 0 {
            v.swap_remove(i);
        }
    }
    println!("{:?}", v);
}

The first is easy and retains the relative order of the un-removed elements, but naturally requires more shuffling. The second requires a little more legwork on your end and destroys the relative ordering, but ensures a minimal number of swaps.


#4

haha, great comments. Just what I needed :slight_smile: Thanks!