Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to interlace an iterator with itself from the end?

I have an iterator in the form 0..=63, i.e.
0 1 2 3 4 ... 59 60 61 62 63.
Its .count() is 64.

How would I get the following iterator:
0 63 1 62 2 61 3 60 4 59 ...
(of course independent of the items present in the iterator), preferably without cloning?
The .count() should stay the same, as only the order of items should change.

I've looked in the standard library and couldn't find it, same in the itertools crate.

like image 804
leo848 Avatar asked Sep 19 '25 17:09

leo848


1 Answers

Here's one way using only the standard library. It requires a DoubleEndedIterator and will skip the last item for odd sized iterators:

fn main() {
    let mut range = (0..=63).into_iter();
    let iter = std::iter::from_fn(|| Some([range.next()?, range.next_back()?])).flatten();
    dbg!(iter.collect::<Vec<_>>());
}

Output:

[src/main.rs:4] iter.collect::<Vec<_>>() = [
    0,
    63,
    1,
    62,
    2,
    61,
    3,
...

    30,
    33,
    31,
    32,
]

Playground


@Finomnis has posted a solution in case your input has an odd number of items.

like image 138
Dogbert Avatar answered Sep 22 '25 07:09

Dogbert