从向量中删除元素

Kai*_*ren 18 rust

有没有一种简单的方法从一个元素中删除元素Vec<T>

有一个叫做的方法remove(),它需要一个index: usize,但是index_of()我甚至都看不到一种方法.

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

Kai*_*ren 22

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

let index = xs.iter().position(|x| *x == some_x).unwrap();
xs.remove(index);
Run Code Online (Sandbox Code Playgroud)

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

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


ant*_*oyo 13

您可以使用该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]
}
Run Code Online (Sandbox Code Playgroud)

  • 找到元素后进行的比较是不必要的 (3认同)
  • @malbarbo 是的,这是因为此方法删除了该值的每个实例。 (2认同)

A.B*_*.B. 10

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);
}
Run Code Online (Sandbox Code Playgroud)

  • @Kai Sellgren:也称为:不要修改您正在迭代的容器。 (4认同)

Luk*_*odt 10

有一个实验API,叫做Vec::remove_item().它仍然不稳定,因此它不适用于稳定的编译器.但它最终可能会变得稳定(跟踪问题).

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

let removed = xs.remove_item(&some_x); 
Run Code Online (Sandbox Code Playgroud)


Wil*_*ner 5

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

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

  • 无论如何,删除操作都是 O(log n),所以这个解决方案不是 O(log n),即使它的搜索部分是。 (3认同)
  • 在 99% 的实际情况下,您想要的数据结构是 HashSet。然后搜索并删除是 O(1)。 (2认同)

Mik*_*mus 5

extract_if()上次的答案是新的吗?

似乎与凯的回答相似:

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

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

assert_eq!(numbers, vec![1, 3, 5, 9, 11, 13, 15]);
Run Code Online (Sandbox Code Playgroud)

https://doc.rust-lang.org/std/vec/struct.Vec.html#method.extract_if