itertools
itertools copied to clipboard
Would `filter_position` or the like be worth adding?
In a private project of mine I need to handle a lot of vectors and iterators, and as such I found myself writing things equivalent to
source.take(n).skip(1).chain(source.skip(n + 1))
or
source.enumerate().filter(|(i, _)| i != n_1 && i != n_2).map(|(_, x)| x)
pretty often. So I wondered if it would be worth adding a function with a signature like this to Itertools?
fn filter_position<P>(self, predicate: P) -> FilterPosition<Self, P>
where Self: sized,
P: FnMut(usize) -> bool,
I'd be happy to implement this. But if anyone has a better suggestion for the name/signature/the problem solution itself, I'd be happy to read it, too!
filter_map can help here. Something like this
source.enumerate().filter_map(|(i, x)| (i != n_1 && i != n_2).then_some(x))
Alternatively, you could do it with a stateful adapter. Perhaps
source.filter(index_filter(|i| i != n_1 && i != n_2))
via a helper like
fn index_filter<T>(mut p: impl FnMut(usize) -> bool) -> impl for<'a> FnMut(&'a T) -> bool {
let mut next = 0;
move |_| {
let i = next;
next += 1;
p(i)
}
}
The filter_map solution is really elegant, thank you! Do you think then that filter_position would have a purpose? It's less to type, but also less powerful.