I'm looking for an iterator adapter that combines (multiplexes) the elements of two input iterators by conditionally replacing elements from the primary input iterator with those from the secondary input iterator, based on some predicate function.
For illustration I'm looking for an iterator kinda like this
struct MuxIter<A, B, F> {
primary: A, // primary input iterator
secondary: B, // secondary input iterator
predicate: F, // predicate that determines which input iterator to yield values from
}
impl<A, B, F, T> Iterator for MuxIter<A, B, F>
where
A: Iterator<Item = T>,
B: Iterator<Item = T>,
F: Fn(&T) -> bool,
{
type Item = T;
#[rustfmt::skip]
fn next(&mut self) -> Option<Self::Item> {
let elem = self.primary.next()?; // First get the next element from the main iterator
if (self.predicate)(&elem) { // Check if it passes the predicate...
Some(elem) // If it does, yeild it
} else {
self.secondary.next() // if it doesn't, yeild the next element from the secondary iterator instead
}
}
}
See playground for full illustration of this in action.
Does such an iterator exist in std or in a 3rd party crate?
There is a facility in
stdthat can be used to implement this:filter_map.Note that there is a bug in your implementation: if the predicate returns
falseand the secondary iterator has no more items, your iterator will returnNoneinstead of continuing to the next element from the primary iterator. Thefilter_map-based iterator above does not have this bug.