2016-08-12 7 views
2

インデックスをループするには、次/前のアイテムを追跡して、次のようにします。循環ラップされたインデックスを反復処理する最良の方法はありますか?

を1によって相殺することができ、インデックスラッピングを提供する:

for index_prev in 0..n { 
    let index_next = (index_prev + 1) % n; 

    // some arbitrary code... 
    some_function(index_prev, index_next); 
} 

これはモジュロを避け、代わりに行うことによって、より効率的に行うことができます。

let mut index_prev = n - 1; 
for index_next in 0..n { 

    // some arbitrary code... 
    some_function(index_prev, index_next); 

    index_prev = index_next; 
} 

これは動作しますが、それはいくつかの欠点があります:私たちは本当に不変インデックスをループにしたいとき

  • index_prevは、可変宣言する必要があります。
  • index_prevは、forループに限定されるのではなく、外側のスコープのname-spaceで宣言する必要があります。これらのどちらもひどいをしている間

は、彼らが理想的なソリューションよりも少なくなります。


ルーストにこれを行うためのパフォーマンス&便利な方法はありますか、カスタムイテレータを書く必要がありませんか?

錆でこれを行うにはどうすればよいですか?

答えて

3
fn main() { 
    let n = 10; 
    for (prev, next) in (0..n).zip(1..n+1) { 
     println!("{}, {}", prev, next % n); 
    } 
} 

はあなたを与える:

0, 1 
1, 2 
.... 
9, 0 

それとも、本当に剰余を使用しない場合は、次のようになります

for (prev, next) in (0..n).zip((0..n).cycle().skip(1)) { 

は動作しますが、そうであってもより多くのコードを生成します。

また、反復の独自の実装に必要な型をラップするか、またはオーバーフローを正しく処理する[x] getterをラップすることもできます。つまり、常に下位の構造から[x%n]を取得します。

+0

最初の例の下側は、参照するたびに 'next%n'を使う必要があります。誤って 'vector [next]'を使用すると、インデックスエラーが発生します(毎回モジュロを使用する可能性のあるオーバーヘッドと追加の型指定が必要です)。 – ideasman42

+0

@ ideasman42あなたが知っているのは、これがいくつかのCPU負荷の高いループの中心でなければ、余分なモジュールが目立たないことでしょう。もう1つの選択肢は、より高いインデックスを実装し、透過的にラップを行う構造にバッファをラップすることです。それを取り除くことはできませんが、それを忘れることは不可能になります。 – viraptor

+0

私の主な関心事は、 'vector [next]'は正しいコードとして読み込みますが、うまくいかないか、悪化するということです。実際には、 'n 'は' path.to.some.vector.len() 'であり、' vector [next%path.to.some.vector.len()] 'を書くのが面倒です。 – ideasman42

関連する問題