Closed dev-ardi closed 1 week ago
You're looking for https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.partition or https://docs.rs/itertools/latest/itertools/trait.Itertools.html#method.partition_map
It can't be done lazily.
It can't be done lazily.
Yeah you're right, I thought that it could be possible. What about something like
fn filter_callback<P, F>(self, predicate: P, callback: F) -> FilterCallback<Self, P, F>
where
Self: Sized,
P: FnMut(&Self::Item) -> bool,
F: FnMut(&Self::Item)
To do something like
let iter = [1,2,3,4,5].iter().filter_callback(|x| (x % 2 == 0), |x| println!("{x} was odd!"));
I wouldn't bother adding that, because multi-callback things like that are usually bad.
That one would, for example, I think be better done with something like
.filter_map(|x| if x % 2 == 0 { Some(x) } else { println!("{x} was odd!"); None })
Completely fair.
multi-callback things like that are usually bad.
What about things like Option::map_or_else
?
That's actually my go-to example of a horrible API, particularly because the closures are in the opposite order from what everyone expects it to be (which is even worse in the Result
version).
But it also shows how things like foo.map_or_else(|| local + 2, |y| local * y)
end up not working because it tried to move local
twice, whereas if you just write
if let Some(y) = foo { local + 2 } else { local * y }
it works just fine, and it's more direct anyway.
Basically, whenever you have two FnOnce
closures where only one can be called, it works particularly badly, because the signature doesn't have a way to communicate that "not both" fact.
It's not as bad when it's multiple closures called multiple times each, but it's still a sign that it might not be a good abstraction.
The idea is to have a
which would be equivalent of
but in a single pass.