itertools icon indicating copy to clipboard operation
itertools copied to clipboard

Would `filter_position` or the like be worth adding?

Open MultisampledNight opened this issue 2 years ago • 2 comments

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!

MultisampledNight avatar Apr 03 '23 19:04 MultisampledNight

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)
    }
}

scottmcm avatar Apr 03 '23 20:04 scottmcm

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.

MultisampledNight avatar Apr 03 '23 20:04 MultisampledNight