Skip to content

Instantly share code, notes, and snippets.

@Thell
Last active March 20, 2023 06:40
Show Gist options
  • Save Thell/8c8b0e8371700c72cca0a4aa767996db to your computer and use it in GitHub Desktop.
Save Thell/8c8b0e8371700c72cca0a4aa767996db to your computer and use it in GitHub Desktop.
Impls for retain methods with enumerate and with access to the remaining elements for predicate.
trait EnumeratedRetain<T> {
fn retain_enumerate<F>(&mut self, f: F)
where
F: FnMut(usize, &T) -> bool;
}
impl<T> EnumeratedRetain<T> for Vec<T> {
fn retain_enumerate<F>(&mut self, mut f: F)
where
F: FnMut(usize, &T) -> bool,
{
let len = self.len();
let mut del = 0;
{
let v = &mut **self;
for i in 0..len {
if !f(i, &v[i]) {
del += 1;
} else if del > 0 {
v.swap(i - del, i);
}
}
}
if del > 0 {
self.truncate(len - del);
}
}
}
trait SplitLastRetain<T> {
fn retain_split_last<F>(&mut self, f: F)
where
F: FnMut(&T, &[T]) -> bool;
}
impl<T> SplitLastRetain<T> for Vec<T> {
fn retain_split_last<F>(&mut self, mut f: F)
where
F: FnMut(&T, &[T]) -> bool,
{
let len = self.len();
let mut del = 0;
{
let v = &mut **self;
for i in 0..len {
if !f(&v[i], &v[i + 1..]) {
del += 1;
} else if del > 0 {
v.swap(i - del, i);
}
}
}
if del > 0 {
self.truncate(len - del);
}
}
}
@Thell
Copy link
Author

Thell commented Mar 20, 2023

Based on this SO answer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment