2016-04-22 18 views
3

私はイテレータを持っていますiter;各N番目の要素を反復するイテレータに変換することは可能ですか? iter.skip_each(n - 1)のようなもの?各N番目の値を返すイテレータ

+2

'itertools'に' step'イテレータがあります:https://bluss.github.io/rust-itertools/doc/itertools/trait.Itertools.html#method.step – Dogbert

+1

私は何かを望んでいましたが標準ライブラリ。現在Rustを使用している設定では、外部クレートを使用するのが不便です。 – anula

+2

あなたは本当に悪い時を過すでしょう。サードパーティの箱を簡単に使用できるようにするために多大な労力が費やされています。したがって、依存関係を追加することは簡単なことではないという前提のもとで動作します。これは単なる文化的なものではなく、標準ライブラリからの省略を正当化するために積極的に使用されています。私はあなたの状況が何であるか分かりませんが、それを解決するために努力すべきです。 – delnan

答えて

7

Dogbert saidとしては、itertools' stepを使用してください。

外部クレートを使用できない場合、あなたは傷ついてしまうだろう。錆の生態系は、すべてが木箱に押し込まれることを強く奨励します。リポジトリをローカルでクローンし、可能であればその方法で使用してください。

そうでない場合は、それを自分で書く:

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のサイクルのどこにあるかを指定しなかったので、コードを作成するのが最も簡単なものを選択しました。

+0

それはかなり良い解決策です。標準的な図書館には何もないので、私は外部箱を必要としないなら、それを実装する以外の方法はないと思います。 「あなたがNの繰り返しのどこにあるのかを指定しなかったのですが、x.iter()。skip(3).every_nth(5) 'を使用するだけでしたウィンドウを少しシフトする。 – anula

関連する問題