If I have a Vec
I can iterate over elements using an index via v.iter().enumerate()
, and I can remove elements via v.retain()
. Is there a way to do both at once?
In this case the index could no longer be used to access the element - it would be the index of the element before the loop was started.
I can implement this myself but to be as efficient as .retain()
I'd need to use unsafe
, which I'd like to avoid.
This is the result I want:
let mut v: Vec<i32> = vec![1, 2, 3, 4, 5, 4, 7, 8];
v.iter()
.retain_with_index(|(index, item)| (index % 2 == 0) || item == 4);
assert(v == vec![1, 3, 4, 5, 4, 7]);
I found essentially the same question on the Rust User's Forum. They suggested this solution, which isn't too bad:
let mut index = 0;
v.retain(|item| {
index += 1;
((index - 1) % 2 == 0) || item == 4
});
At the time it wasn't a valid solution because the iteration order of retain()
was not guaranteed, but happily for me someone in that thread documented the order so now it is. :-)