微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何使用滑动窗口对生成迭代器?

如何解决如何使用滑动窗口对生成迭代器?

我想为此输入创建一个迭代器:

[1,2,3,4]

将包含以下内容

(1,2)
(2,3)
(3,4)

Peekable 似乎很适合这个,但我是 Rust 的新手,所以这个简单的版本不起作用:

fn main() {
  let i = ['a','b','c']
    .iter()
    .peekable();
  let j = i.map(|x| (x,i.peek()));
  println!("{:?}",j);
  println!("Hello World!");
}

我做错了什么?

解决方法

您可以使用 itertools 板条箱中的 tuple_windows() 作为直接替代品:

use itertools::Itertools;

fn main() {
    let data = vec![1,2,3,4];
    for (a,b) in data.iter().tuple_windows() {
        println!("({},{})",a,b);
    }
}
(1,2)
(2,3)
(3,4)
,

您可以对切片使用 windows 方法,然后将数组映射为元组:

fn main() {
    let i = [1,4]
        .windows(2)
        .map(|pair| (pair[0],pair[1]));
    println!("{:?}",i.collect::<Vec<_>>());
}

playground


如果您想要一个适用于所有迭代器(而不仅仅是切片)的解决方案并且愿意使用第 3 方库,您可以使用 itertools 中的 tuple_windows 方法。

use itertools::{Itertools,TupleWindows}; // 0.10.0

fn main() {
    let i: TupleWindows<_,(i32,i32)> = vec![1,4]
        .into_iter()
        .tuple_windows();
    println!("{:?}",i.collect::<Vec<_>>());
}

playground


如果您不愿意使用 3rd 方库,它仍然很简单,您可以自己实现它!下面是一个适用于任何 Iterator<Item = T> where T: Clone:

的示例通用实现
use std::collections::BTreeSet;

struct PairIter<I,T>
where
    I: Iterator<Item = T>,T: Clone,{
    iterator: I,last_item: Option<T>,}

impl<I,T> PairIter<I,{
    fn new(iterator: I) -> Self {
        PairIter {
            iterator,last_item: None,}
    }
}

impl<I,T> Iterator for PairIter<I,{
    type Item = (T,T);
    fn next(&mut self) -> Option<Self::Item> {
        if self.last_item.is_none() {
            self.last_item = self.iterator.next();
        }
        if self.last_item.is_none() {
            return None;
        }
        let curr_item = self.iterator.next();
        if curr_item.is_none() {
            return None;
        }
        let temp_item = curr_item.clone();
        let result = (self.last_item.take().unwrap(),curr_item.unwrap());
        self.last_item = temp_item;
        Some(result)
    }
}

fn example<T: Clone>(iterator: impl Iterator<Item = T>) -> impl Iterator<Item = (T,T)> {
    PairIter::new(iterator)
}

fn main() {
    let mut set = BTreeSet::new();
    set.insert(String::from("a"));
    set.insert(String::from("b"));
    set.insert(String::from("c"));
    set.insert(String::from("d"));
    dbg!(example(set.into_iter()).collect::<Vec<_>>());
}

playground

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。