rust 如何从最后开始将迭代器与其自身交错?

bxjv4tth  于 2022-11-24  发布在  其他
关注(0)|答案(3)|浏览(142)

我有一个0..=63形式的迭代器,即
0 1 2 3 4 ... 59 60 61 62 63 .
它的.count()是64。
下面的代码是:
0 63 1 62 2 61 3 60 4 59 ...
(of独立于迭代器中存在的项的过程),最好不进行克隆?
.count()应该保持不变,因为只有项目的顺序应该改变。
我在标准库中找过了,但找不到它,在itertools板条箱中也是如此。

68de4m5k

68de4m5k1#

这里有一种只使用标准库的方法,它需要一个DoubleEndedIterator,并且对于奇数大小的迭代器会跳过最后一项:

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<_>>());
}

输出量:

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

    30,
    33,
    31,
    32,
]

Playground
@Finomnis has posted a solution,以防您的输入包含奇数个项目。

pnwntuvh

pnwntuvh2#

此解决方案适用于实现DoubleEndedIterator的所有迭代器:
注意,这个解决方案保证返回所有项,不管迭代器包含的是偶数还是奇数。
第一个
其思想是存储下一项应该是从前面还是从后面,然后在每次迭代中翻转它。
from_fn可以接受FnMut,也就是说,它可以接受存储内部状态的闭包。这个闭包中的内部状态由变量iterfrom_front组成,它们通过move ||关键字被移动到闭包中。

dbf7pr2w

dbf7pr2w3#

您可以使用itertools::interleave来交错正向和反向迭代器。

  • RangeInclusive<i32>没有实现ExactSizedIterator,所以没有.len()函数,我们必须自己计算。
  • 如果范围长度为奇数,则由于(len + 1),额外的项将显示在前半部分。
let range = 0..=63;
let len = range.end() - range.start() + 1;
let iter = itertools::interleave(
    range.clone().take((len + 1) / 2),
    range.clone().rev().take(len / 2),
);

Playground

相关问题