返回每个第N个值的迭代器

anu*_*ula 3 rust

我有一个迭代器iter; 是否可以将其转换为迭代每个第N个元素的迭代器?有点像iter.skip_each(n - 1)

She*_*ter 7

正如Dogbert所说,使用itertools'step.

如果你不能使用外部板条箱,你将会处于一个受伤的世界.Rust生态系统强烈鼓励将所有东西推到板条箱.也许您应该只在本地克隆存储库并尽可能地使用它.

否则,自己写:

use std::iter::Fuse;

struct Nth<I> {
    n: usize,
    iter: Fuse<I>,
}

impl<I> Iterator for Nth<I>
    where I: Iterator
{
    type Item = I::Item;

    fn next(&mut self) -> Option<Self::Item> {
        let mut nth = None;

        for _ in 0..self.n {
            nth = self.iter.next();
        }

        nth
    }
}

trait EveryNth: Iterator + Sized {
    fn every_nth(self, n: usize) -> Nth<Self> {
        Nth { n: n, iter: self.fuse() }
    }
}

impl<I> EveryNth for I where I: Iterator {}

fn main() {
    let x = [1,2,3,4,5,6,7,8,9];

    for v in x.iter().every_nth(1) { println!("{}", v) }
    println!("---");
    for v in x.iter().every_nth(2) { println!("{}", v) }
    println!("---");
    for v in x.iter().every_nth(3) { println!("{}", v) }
    println!("---");
    for v in x.iter().every_nth(4) { println!("{}", v) }
    println!("---");
    for v in x.iter().every_nth(5) { println!("{}", v) }
    println!("---");
    for v in x.iter().every_nth(6) { println!("{}", v) }
}
Run Code Online (Sandbox Code Playgroud)

请注意,这与itertools的行为不同.你没有指定迭代器选择的N循环中的位置,所以我选择了最容易编码的那个.


Fun*_*uit 6

从 Rust 1.26 开始,Iterator::step_by标准库中有这个方法:

基本用法:

let a = [0, 1, 2, 3, 4, 5];
let mut iter = a.iter().step_by(2);

assert_eq!(iter.next(), Some(&0));
assert_eq!(iter.next(), Some(&2));
assert_eq!(iter.next(), Some(&4));
assert_eq!(iter.next(), None);
Run Code Online (Sandbox Code Playgroud)