gpt4 book ai didi

rust - 从 Rust 中的 Vec 中删除一系列值?

转载 作者:行者123 更新时间:2023-11-29 08:17:32 25 4
gpt4 key购买 nike

removeVec 上删除一个由索引给出的值,并返回该值。

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

所以,如果我从 let mut v = vec![2,3,4,5,6,7] 开始,并删除索引 [1,2,5],我最终会得到一个包含 vec![3,4,7] 的新向量,而 v 将是 vec![2,5 ,6]

最佳答案

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

take_multiple()take_multiple_in_order() 将完全按照您在原始问题中的要求执行。

pub trait RemoveMultiple<T> {
/// Remove multiple indices
fn remove_multiple(&mut self, to_remove: Vec<usize>);

/// Remove multiple indices with swap_remove, this is faster but reorders elements
fn swap_remove_multiple(&mut self, to_remove: Vec<usize>);

/// Remove and return multiple indices
fn take_multiple(&mut self, to_remove: Vec<usize>) -> Vec<T>;

/// Remove and return multiple indices, preserving the order specified in the index list
fn take_multiple_in_order(&mut self, to_remove: &[usize]) -> Vec<T>;

/// Remove and return multiple indices with swap_remove, this is faster but reorders elements and the results are in reverse order
fn swap_take_multiple(&mut self, to_remove: Vec<usize>) -> Vec<T>;
}

impl<T> RemoveMultiple<T> for Vec<T> {
fn remove_multiple(&mut self, mut to_remove: Vec<usize>) {
to_remove.sort();
to_remove.reverse();
for r in to_remove {
self.remove(r);
}
}

fn swap_remove_multiple(&mut self, mut to_remove: Vec<usize>) {
to_remove.sort();
to_remove.reverse();
for r in to_remove {
self.swap_remove(r);
}
}

fn take_multiple(&mut self, mut to_remove: Vec<usize>) -> Vec<T> {
to_remove.sort();
to_remove.reverse();
let mut collected = vec![];
for r in to_remove {
collected.push(self.remove(r));
}
collected.reverse();
collected
}

fn take_multiple_in_order(&mut self, to_remove: &[usize]) -> Vec<T> {
let mut to_remove = to_remove.iter().copied().enumerate().collect::<Vec<_>>();
to_remove.sort_by_key(|(_, r)| *r);
to_remove.reverse();
let mut collected : Vec<Option<T>> = std::iter::repeat_with(|| None).take(to_remove.len()).collect();
for (i, r) in to_remove {
collected[i] = Some(self.remove(r));
}
collected.into_iter().filter_map(|x| x).collect()
}

fn swap_take_multiple(&mut self, mut to_remove: Vec<usize>) -> Vec<T> {
to_remove.sort();
to_remove.reverse();
let mut collected = vec![];
for r in to_remove {
collected.push(self.swap_remove(r));
}
collected
}
}


#[cfg(test)]
mod test {
use super::*;

#[test]
fn remove_multiple() {
let mut list = vec!['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
list.remove_multiple(vec![8, 0, 5, 6]);
assert_eq!(vec!['1', '2', '3', '4','7', '9'], list);
}

#[test]
fn swap_remove_multiple() {
let mut list = vec!['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
list.swap_remove_multiple(vec![8, 0, 5, 6]);
assert_eq!(vec!['9', '1', '2', '3', '4', '7'], list);
}

#[test]
fn take_multiple() {
let mut list = vec!['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
let taken = list.take_multiple(vec![8, 0, 5, 6]);
assert_eq!(vec!['1', '2', '3', '4','7', '9'], list);
assert_eq!(vec!['0', '5', '6', '8'], taken);
}

#[test]
fn swap_take_multiple() {
let mut list = vec!['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
let taken = list.swap_take_multiple(vec![8, 0, 5, 6]);
assert_eq!(vec!['9', '1', '2', '3', '4', '7'], list);
assert_eq!(vec!['8', '6', '5', '0'], taken);
}

#[test]
fn take_multiple_in_order() {
let mut list = vec!['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
let taken = list.take_multiple_in_order(&vec![8, 0, 5, 6]);
assert_eq!(vec!['1', '2', '3', '4','7', '9'], list);
assert_eq!(vec!['8', '0', '5', '6'], taken);
}
}

关于rust - 从 Rust 中的 Vec 中删除一系列值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57947441/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com