从向量中删除元素

时间:2014-10-07 18:45:31

标签: rust

是否有一种简单的方法可以从Vec<T>删除元素?

有一个名为remove()的方法,它需要index: usize,但我甚至没有index_of()方法。

我正在寻找(希望)简单和O(n)的东西。

6 个答案:

答案 0 :(得分:19)

这是我到目前为止所做的事情(这也使借阅检查员感到高兴):

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

我还在等待找到更好的方法,因为这非常难看。

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

答案 1 :(得分:9)

迭代器有一个position()方法,它返回与谓词匹配的第一个元素的索引。相关问题:Is there an equivalent of JavaScript's indexOf for Rust arrays?

代码示例:

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);
}

答案 2 :(得分:9)

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

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

答案 3 :(得分:8)

有一个名为Vec::remove_item()的实验性API。它仍然不稳定,因此它不适用于稳定的编译器。但它最终可能会变得稳定(tracking issue)。

使用这种方法,做你想要的事情很容易:

let removed = xs.remove_item(&some_x); 

答案 4 :(得分:0)

drain_filter() 是最新的答案吗?

似乎与凯的回答相似:

#![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#method.drain_filter

答案 5 :(得分:-1)

如果您的数据已排序,请使用二进制搜索来O(log n)删除,这对于大型输入而言可能要快得多。

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