Q:

How can I avoid moving out of a borrow when removing values from a borrowed Vec?

I have a struct that does not implement Clone or Copy:
struct MyStruct {
    data: Vec<MyData>,
}

I'd like to write a function on the struct that "cleans up" data that's no longer valid: 
fn clean_up(&mut self) {
    self.data = self.data.into_iter()
      .filter(|data| data.is_still_valid())
      .collect()
}

This doesn't work, the compiler complains that I'm moving out of a borrowed context when I use into_iter. Without into_iter, it fails because I'm creating a Vec of &MyData, not MyData.
I can fix this by writing something like the following instead, but it is far less readable:
let mut invalid_indicies = vec![];
for (i, data) in self.data.iter().enumerate() {
    if !data.is_still_valid() {
        invalid_indicies.push(i);
    }
}
for i in invalid_indicies {
    self.data.remove(i);
}

Is it possible to use filter and similar sequence operators to modify vectors owned by a struct while still borrowing instead of moving self in clean_up()?

A:

You can use Vec::retain to remove items from the vector in place:
fn clean_up(&mut self) {
    self.data.retain(|data| data.is_still_valid());
}

