I have an iterator iter
; is it possible to convert it into an iterator that iterates over each Nth element? Something like iter.skip_each(n - 1)
?
As of Rust 1.26, there is the Iterator::step_by
method in the standard library:
Basic usage:
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);
As Dogbert said, use itertools' step
.
You are going to be in a world of hurt if you can't use external crates. The Rust ecosystem strongly encourages everything to be pushed to crates. Maybe you should just clone the repository locally and use it that way if you can.
Otherwise, write it yourself:
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) }
}
Note this is different behavior from itertools. You didn't specify where in the cycle of N the iterator picks from, so I chose the one that was easiest to code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With