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

时间:2016-04-22 15:37:47

标签: rust

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

这样的东西

2 个答案:

答案 0 :(得分:7)

作为Dogbert said,请使用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) }
}

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

答案 1 :(得分:0)

自2016年以来,此答案已更改!现在有一种标准方法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);