@Timmmm和@Hauleth的回答非常务实,我想提供几个替代方案。
这是一个带有一些基准和测试的游乐场:
https ://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=cffc3c39c4b33d981a1a034f3a092e7b
这很难看,但如果你真的想要一个方法,你可以用一个新的特性v.retain_with_index()
对方法做一些复制粘贴:retain
trait IndexedRetain<T> {
fn retain_with_index<F>(&mut self, f: F)
where
F: FnMut(usize, &T) -> bool;
}
impl<T> IndexedRetain<T> for Vec<T> {
fn retain_with_index<F>(&mut self, mut f: F)
where
F: FnMut(usize, &T) -> bool, // the signature of the callback changes
{
let len = self.len();
let mut del = 0;
{
let v = &mut **self;
for i in 0..len {
// only implementation change here
if !f(i, &v[i]) {
del += 1;
} else if del > 0 {
v.swap(i - del, i);
}
}
}
if del > 0 {
self.truncate(len - del);
}
}
}
这样该示例将如下所示:
v.retain_with_index(|index, item| (index % 2 == 0) || item == 4);
或者...更好的是,您可以使用高阶函数:
fn with_index<T, F>(mut f: F) -> impl FnMut(&T) -> bool
where
F: FnMut(usize, &T) -> bool,
{
let mut i = 0;
move |item| (f(i, item), i += 1).0
}
这样示例现在看起来像这样:
v.retain(with_index(|index, item| (index % 2 == 0) || item == 4));
(我的偏好是后者)