2017-12-05 7 views
2

[1,2,2,3,4,4]は、[2,4]を生成するはずの番号だけを見つける必要があります。次の番号を覗いてみる必要があるので、Peekable iteratorを試してみてfilterと書いてみました。フィルタークローズでPeekableイテレーターを使用するにはどうすればよいですか?

fn main() { 
    let xs = [1, 2, 2, 3, 4, 4]; 
    let mut iter = xs.iter().peekable(); 

    let pairs = iter.filter(move |num| { 
     match iter.peek() { 
      Some(next) => num == next, 
      None  => false, 
     } 
    }); 

    for num in pairs { 
     println!("{}", num); 
    } 
} 

私はエラーを取得する:

error[E0382]: capture of moved value: `iter` 
--> src/main.rs:6:15 
    | 
5 |  let pairs = iter.filter(move |num| { 
    |     ---- value moved here 
6 |   match iter.peek() { 
    |    ^^^^ value captured here after move 
    | 
    = note: move occurs because `iter` has type `std::iter::Peekable<std::slice::Iter<'_, i32>>`, which does not implement the `Copy` trait 

私はiterが閉鎖によって使用されているため、これはあると思うが、それはそれを借りていない、そしてそれは、それをコピーすることはできません。

フィルタ内のイテレータを参照したいというこの問題をどのように解決できますか?

答えて

3

refer to the iterator inside a filter

私はあなたができるとは思わない。あなたがそれを行うと、それは

fn filter<P>(self, predicate: P) -> Filter<Self, P> 
where 
    P: FnMut(&Self::Item) -> bool, 

を行っています:あなたはfilterを呼び出すと、それはベースイテレータの所有権を取得します。もうiterはありません。いくつかの同様のケースでは、Iterator::by_refを使用してイテレータを可変的に借用し、しばらくドライブしてから元のものに戻すことができます。この場合、内側のイテレータは2度目にそれを可変的に借りる必要があるため、この場合は動作しません。これは許可されません。

find only the numbers where the next number is the same.

extern crate itertools; 

use itertools::Itertools; 

fn main() { 
    let input = [1, 2, 2, 3, 4, 4]; 

    let pairs = input 
     .iter() 
     .tuple_windows() 
     .filter_map(|(a, b)| if a == b { Some(a) } else { None }); 

    let result: Vec<_> = pairs.cloned().collect(); 
    assert_eq!(result, [2, 4]); 
} 

それともあなただけの標準ライブラリ使用して何かをしたかった場合:スライスの特定の場合には

fn main() { 
    let xs = [1, 2, 2, 3, 4, 4]; 

    let mut prev = None; 
    let pairs = xs.iter().filter_map(move |curr| { 
     let next = if prev == Some(curr) { Some(curr) } else { None }; 
     prev = Some(curr); 
     next 
    }); 

    let result: Vec<_> = pairs.cloned().collect(); 
    assert_eq!(result, [2, 4]); 
} 
+2

、[ '.windows()'](https://でドキュメントを。 rust-lang.org/std/slice/struct.Windows.html)は、ウィンドウとしてサブスライスを生成します。これは、汎用ではありませんが、 'tuple_windows'と比較的同等です。 –

関連する問題