I made this function which should remove all adjacent values it finds from a vector.
fn remove_adjacent<T: std::cmp::PartialEq>(values: &mut Vec<T>, item: T) {
let mut offset = 0;
while let Some(idx) = values.iter().skip(offset).position(|n| *n == item) {
let length = values
.iter()
.skip(idx)
.position(|v| *v != item)
.unwrap_or(values.len() - idx);
if length > 1 {
values.drain(idx + 1..length + idx);
}
offset = idx + 1;
}
}
It works fine for vectors like
vec![2, 1, 3, 3, 3, 3, 3];
But not for vectors whose target element to be removed repeats after a non-target value, like
vec![2, 1, 3, 3, 3, 3, 3, 7, 3, 3, 3];
It should also remove the threes 3
values after 7
, but instead it get stuck in an infinite loop. I'm not able find the error on my own, if anyone has tips on how to fix this I'll really appreciate it.
Everything in your code works correctly except getting the idx
.
You can print out the idx
and see what is wrong with it. Printing offset
helps too.
fn remove_adjacent<T: std::cmp::PartialEq>(values: &mut Vec<T>, item: T) {
let mut offset = 0;
while let Some(idx) = values.iter().skip(offset).position(|n| *n == item) {
dbg!(idx, offset); // prints out nicely
let length = values
.iter()
.skip(idx)
.position(|v| *v != item)
.unwrap_or(values.len() - idx);
if length > 1 {
values.drain(idx + 1..length + idx);
}
offset = idx + 1;
}
}
You will notice that the idx
is not always what you want.
This is happening becuase .position(
counts not in values
but in the iterator you get after .skip(offset)
.
I hope looking at the printed values and my clue guides you to fix the error on your own. Good luck! 😃