Idiomatic way to filter a collection stored in a struct using iterators

A stand-alone collection can be filtered like so:

fn main() {
    let mut x: Vec<_> = (1..10).collect();

    let i = 2;
    x = x.into_iter().filter(|&x| x % i == 0).collect();

    assert_eq!(vec![2, 4, 6, 8], x);
}

But it doesn't seem to be possible to use into_iter() if x is stored in a struct. So what is the idiomatic way to filter a collection stored in struct? I came up with the following solution that works but I'm wondering if there is something that looks more like the simple case shown above.

struct Foo {
    x: Vec<usize>,
}

impl Foo {
    fn fltr(&mut self, i: usize) {
        self.x = self.x.iter().filter(|&&x| x % i == 0).map(|x| *x).collect();
    }
}

fn main() {
    let mut foo = Foo {
        x: (1..10).collect(),
    };
    foo.fltr(2);

    assert_eq!(vec![2, 4, 6, 8], foo.x);
}

Using the retain method, one can filter items based on a predicate of a Vec in place.

6 Likes
struct Foo {
    bar: Vec<usize>
}

impl Foo {
    fn filter(&mut self, i: usize) {
        self.bar.retain(|x| x % i == 0);
    }
}

fn main() {
    let mut foo = Foo {
        bar: (1..10).collect()
    };
    foo.filter(2);
    assert_eq!(vec![2, 4, 6, 8], foo.bar);
}
1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.