I would like to apply some arbitrary number of filters based on external input to a list.
This is my best attempt at doing so, but the types don't check out because iterator.filter() is of type Filter<Iter> so second iteration on the for loop will be a Filter<Filter<Iter>> and so on, which means the types don't match.
let numbers = vec![1, 2, 3, 4];
let mut iterator = my_list.iter();
for number in numbers {
iterator = iterator.filter(|x| x < number)
}
iterator.collect()
I imagine there must be a better way to do this. Anyone have any ideas?
Thanks!
Use Iterator::filter() exactly once, then inside the filter function, have it check all of the externally provided filter conditions.
let mut iterator = my_list.iter().filter(|&x| numbers.iter().all(|n| x < n));
The general technique to keep in mind here is: when you want an Iterator (or sometimes Future or other trait implementation) that seems to need to be of different types in different cases, you can often find a way to move the difference out of the type and into the code you provide (here in the function passed to filter()).
If necessary, you can also use either to unify two different types of iterators, or Box<dyn Iterator<Item = ...>> for arbitrary iterators. You could make your loop work with Box<dyn Iterator>, but that would usually be a poor choice because it would be building a linked list of dynamically-dispatched iterator adapters — much less efficient than the above code.