从向量中删除一个元素

有没有一种简单的方法可以从 Vec<T>中移除一个元素?

有一个叫做 remove()的方法,它接受一个 index: usize,但是我看不到一个 index_of()方法。

我正在寻找一些(希望)简单和 O (n)。

98408 次浏览

有一个用于迭代器的 position()方法,它返回与谓词匹配的第一个元素的索引。相关问题: 对于 Rust 数组,是否有相当于 JavaScript 的 indexOf的代码

还有一个代码示例:

fn main() {
let mut vec = vec![1, 2, 3, 4];


println!("Before: {:?}", vec);


let removed = vec.iter()
.position(|&n| n > 2)
.map(|e| vec.remove(e))
.is_some();


println!("Did we remove anything? {}", removed);


println!("After: {:?}", vec);
}

这就是我到目前为止得出的结论(这也让借款检查器感到高兴) :

let index = xs.iter().position(|x| *x == some_x).unwrap();
xs.remove(index);

我还在等着找到更好的办法,因为这太丑陋了。

注意: 我的代码假设元素确实存在(因此是 .unwrap())。

您可以使用 retain,但它会删除值的每个实例:

fn main() {
let mut xs = vec![1, 2, 3];
let some_x = 2;
xs.retain(|&x| x != some_x);
println!("{:?}", xs); // prints [1, 3]
}

您的问题未指明: 您想返回的 所有项目等于您的针或只是 ?如果有,是 第一还是 最后?如果没有一种元素可以和你的针相提并论呢?它可以与快速 swap_remove或你需要较慢的 remove删除?为了迫使程序员考虑这些问题,没有简单的方法来“删除一个项”(参见 这个讨论了解更多信息)。

删除等于 needle第一元素

// Panic if no such element is found
vec.remove(vec.iter().position(|x| *x == needle).expect("needle not found"));


// Ignore if no such element is found
if let Some(pos) = vec.iter().position(|x| *x == needle) {
vec.remove(pos);
}

你当然可以处理 None的情况下,只要你喜欢(恐慌和忽略不是唯一的可能性)。

删除等于 needle最后元素

与第一个元素类似,但是用 rposition替换 position

删除等于 needle所有元素

vec.retain(|x| *x != needle);

或者 swap_remove

请记住,remove的运行时为 O (n) ,因为索引之后的所有元素都需要移位。Vec::swap_remove的运行时为 O (1) ,因为它将要删除的元素与最后一个元素交换。如果元素的顺序在您的情况下并不重要,那么使用 swap_remove而不是 remove

如果您的数据排序为 ,请使用二进制搜索删除 O(log n),这对于大输入来说会快得多。

match values.binary_search(value) {
Ok(removal_index) => values.remove(removal_index),
Err(_) => {} // value not contained.
}

从上一个答案来看 drain_filter()是新的吗?

似乎与 Kai 的回答相似:

#![feature(drain_filter)]
let mut numbers = vec![1, 2, 3, 4, 5, 6, 8, 9, 11, 13, 14, 15];


numbers.drain_filter(|x| *x % 2 == 0).collect::<Vec<_>>();


assert_eq!(numbers, vec![1, 3, 5, 9, 11, 13, 15]);

Https://doc.rust-lang.org/std/vec/struct。 Vec.html # 方法