Removing elements from a Vec based on some condition

前端 未结 2 1434
伪装坚强ぢ
伪装坚强ぢ 2020-11-27 23:26

My code looks like this:

struct Bar {
    i: i32,
}

struct Foo {
    v: Vec,
}

impl Foo {
    fn foo(&mut self) {
        self.v.drain(self.         


        
相关标签:
2条回答
  • 2020-11-27 23:53

    In nightly Rust, you can use Vec::drain_filter:

    #![feature(drain_filter)]
    
    #[derive(Debug)]
    struct Bar {
        i: i32,
    }
    
    fn main() {
        let mut bars = vec![Bar { i: 1 }, Bar { i: 10 }, Bar { i: 3 }, Bar { i: 100 }];
        bars.drain_filter(|b| b.i < 10);
        println!("{:?}", bars);
    }
    

    What's extra interesting about drain_filter is that you can get the rejected values as it returns an iterator of them:

    let rejects: Vec<_> = bars.drain_filter(|b| b.i < 10).collect();
    

    You can also choose to modify the value being iterated over:

    bars.drain_filter(|b| {
        b.i -= 1;
        b.i < 10
    });
    
    0 讨论(0)
  • 2020-11-28 00:13

    If you look at the interface of Vec, you will not find a method that erases some elements based on a predicate. Instead you will find retain which keeps the elements based on a predicate.

    Of course, both are symmetric, it's just that retain is harder to find if you filter method names by "remove" or "erase" (it does contain "remove" in its description).

    The example provided speaks for itself:

    let mut vec = vec![1, 2, 3, 4];
    vec.retain(|&x| x % 2 == 0);
    assert_eq!(vec, [2, 4]);
    
    0 讨论(0)
提交回复
热议问题