Rust 从生锈的Vec中删除一系列值?

Rust 从生锈的Vec中删除一系列值?,rust,Rust,Vec上的remove删除索引给定的单个值,并返回该值 我想删除索引列表,例如从长度为8的Vec中删除索引1、2和5,并将这些索引处的值作为另一个Vec获取。重复调用remove会(a)代价高昂,(b)容易出错,因为每次移动remove其他索引之后都会发生错误 所以,如果我从开始,让mut v=vec![2,3,4,5,6,7],并删除索引[1,2,5],我将得到一个包含向量的新向量![3,4,7],而v将是vec![2,5,6]如果要删除的索引是连续的,可以使用Vec::drain,如中所示。

Vec上的
remove
删除索引给定的单个值,并返回该值

我想
删除
索引列表,例如从长度为8的
Vec
中删除索引1、2和5,并将这些索引处的值作为另一个
Vec
获取。重复调用
remove
会(a)代价高昂,(b)容易出错,因为每次移动
remove
其他索引之后都会发生错误


所以,如果我从
开始,让mut v=vec![2,3,4,5,6,7]
,并删除索引
[1,2,5]
,我将得到一个包含
向量的新向量![3,4,7]
,而
v
将是
vec![2,5,6]
如果要删除的索引是连续的,可以使用
Vec::drain
,如中所示。如果没有(即,您有任意的索引要删除),事情就会变得复杂得多

使用
swap\u remove
可以解决
remove
的“昂贵”问题。它不会将所有元素向左移动,而是将移除的元素与最后一个元素交换,因此是一个O(1)操作。然而,由于元素的索引在每次删除操作后都会发生变化,因此使用这种方法仍然非常容易出错。此外,元素的顺序与以前不同,这可能不适合您

有效删除多个任意索引的唯一方法(我能想到)是按降序对这些索引进行排序

//`index_to_remove`必须按降序排序!
fn remove_multiple(来源:&mut Vec,索引_to_remove:&usize])->Vec{
索引_to _remove.iter()
.copied()
.map(| i | source.swap_remove(i))
.collect()
}
示例():

让mut vec=vec!['a','b','c','d','e','f'];
let removed=删除多个(&mut vec,&[5,3,2,0]);
普林顿!(“来源:{:?}”,vec);//['e','b']
普林顿!((“结果:{:?}”,已删除);//[f',d',c',a']

如果你的索引列表没有排序,我实际上认为排序是实现目标最有效的方法。至少我想不出一种算法能够跟踪所有索引,并且比O(n*logn)更快,O(n*logn)是排序的第一运行时

我只是为自己的应用程序解决这个问题,所以我要分享这个模块。它并不完美,我相信它可以优化,但对我来说已经足够好了

take\u multiple()
take\u multiple\u in\u order()
将完全满足您在原始问题中的要求

pub trait removemplex{
///删除多个索引
fn删除多个(mut self,to_remove:Vec)(&mut self);
///使用swap_Remove删除多个索引,这会更快,但会重新排序元素
fn交换\u删除\u多个(&mut self,to\u remove:Vec);
///删除并返回多个索引
fn取多个(&mut self,to_remove:Vec)->Vec;
///删除并返回多个索引,保留索引列表中指定的顺序
fn按顺序取多个(&mut self,to&u remove:&u usize])->Vec;
///使用swap_Remove删除并返回多个索引,这会更快,但会对元素重新排序,结果的顺序与此相反
fn swap_take_multiple(&mut self,to_remove:Vec)->Vec;
}
Vec的impl-RemoveMultiple{
fn删除多个(多个自身,多个到删除:Vec){
删除。排序();
取下。反转();
对于要移除的r in{
自行拆除(r);
}
}
fn交换\u删除\u多个(多个自身,多个到\u删除:Vec){
删除。排序();
取下。反转();
对于要移除的r in{
自交换/移除(r);
}
}
fn取多个(&mut self,mut to_remove:Vec)->Vec{
删除。排序();
取下。反转();
让mut collected=vec![];
对于要移除的r in{
收集、推(自移(r));
}
收集。反向();
收集
}
fn按顺序取多个(&mut self,to_remove:&usize])->Vec{
让mut to_remove=to_remove.iter().copied().enumerate().collect:();
按|(|,r)|*r)键对_进行排序;
取下。反转();
让mut收集:Vec=std::iter::用(| | None)重复_.take(to_remove.len()).collect();
对于(i,r)in,请删除{
收集的[i]=Some(self.remove(r));
}
collected.into_iter().filter_map(|x | x).collect()
}
fn交换\u获取\u多个(&mut self,mut to \u remove:Vec)->Vec{
删除。排序();
取下。反转();
让mut collected=vec![];
对于要移除的r in{
收集。推送(自交换_移除(r));
}
收集
}
}
#[cfg(测试)]
模试验{
使用超级::*;
#[测试]
fn删除\u多个(){
让mut list=vec!['0','1','2','3','4','5','6','7','8','9'];
列表。删除多个(向量![8,0,5,6]);
assert_eq!(vec!['1','2','3','4','7','9',list);
}
#[测试]
fn交换\u删除\u多个(){
让mut list=vec!['0','1','2','3','4','5','6','7','8','9'];
列表。交换/删除/多个(向量![8,0,5,6]);
断言(vec!['9'、'1'、'2'、'3'、'4'、'7'],列表);
}
#[测试]
fn take_multiple(){
让mut list=vec!['0','1','2','3','4','5','6','7','8','9'];
let take=list.take_倍数(vec![8,0,5,6]);
assert_eq!(vec!['1','2','3','4','7','9',list);
assert_eq!(向量!['0','5','6','8',取);
}
#[测试]
fn交换(取多个){
让mut list=vec!['0','1','2','3','4','5','6','7','8','9'];
let take=list.swap_take_multiple(vec![8,0,5,6]);
断言(vec!['9'、'1'、'2'、'3'、'4'、'7'],列表);
断言(向量)['8','6'