This solution works for all iterators that implement DoubleEndedIterator
:
Note that this solution is guaranteed to return all items, regardless of whether the iterator contains an even or odd number of them.
fn selfinterlace<Iter>(mut iter: Iter) -> impl Iterator<Item = Iter::Item>
where
Iter: DoubleEndedIterator,
{
let mut from_front = false;
std::iter::from_fn(move || {
from_front = !from_front;
if from_front {
iter.next()
} else {
iter.next_back()
}
})
}
fn main() {
let range = (0..=8).into_iter();
let iter = selfinterlace(range);
println!("{:?}", iter.collect::<Vec<_>>());
}
[0, 8, 1, 7, 2, 6, 3, 5, 4]
The idea is that you store whether the next item should be from the front or the back, and then flip that in every iteration.
from_fn
can take FnMut
, meaning, it can take closures that store internal state. The internal state in this closure consists of the variables iter
and from_front
, which get moved into the closure through the move ||
keyword.