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

将一个迭代器映射到另一个而不创建新类型

如何解决将一个迭代器映射到另一个而不创建新类型

我想看看我是否可以创建一个接受一种迭代器类型并将其转换为另一种迭代器类型的函数,同时保留像 Map 这样的迭代器类型所具有的功能

    fn cust_chunk<'a,I>(iter: I,n: usize) -> impl Iterator<Item = String>
        where I: Iterator<Item= &'a char>,{
        let res = iter
            .take(n)
            .fold(String::new(),|acc,c| acc + &c.to_string());

        let res = if res == "" {None} else {Some(res)};
        
        res.into_iter()
    }


    #[test]
    fn test_cust_chunk() {
        let td = ['A','B','C','D','E','F'];


        // functions as required,but `it` is sampled each time for this to work.
        // it would be better to sample the output iterator instead
        let mut it = td.iter();
        print!("[");
        while let Some(val) = cust_chunk(&mut it,3).next() {                
            print!("{0},",val);
        }
        println!("]");
        // [ABC,DEF,]


        // only samples the output iterator once,then stops. Can you return an iterator
        // that would sample the input `it` again on .next()?
        // I just wanted to see if I Could do this without introducing new types
        let mut it = td.iter();
        print!("[");
        for val in cust_chunk(&mut it,3) {
            print!("{0},]

        println!("\n---- end stdout ----");
        panic!("stdout")
    }

解决方法

我认为 OP 可能想要的是 Rust 确实拥有的生成器;但目前该功能不在稳定版本中。生成器中的代码看起来有点类似于下面的代码。

这是一种实现类似于生成器的东西的方法。它可以作为 for 循环的一部分被调用,并且它返回的对象(迭代器)将保持其状态并在每次连续调用其 .next() 方法时返回下一个项目块。>

迭代器是通过调用 std::iter::from_fn() 自动生成的。迭代器的 .next() 方法调用回调。

fn chunker<I>(chunk_size    : usize,data          : I
             ) -> impl Iterator<Item = impl Iterator<Item = I::Item>>
where I: Iterator + Clone,I::Item: Clone,{
    let mut p = data.peekable();
    
    std::iter::from_fn(
        move || {
            if p.peek().is_some() {
                let c = p.clone();
                for _ in 0..chunk_size { if p.next().is_none() { break; } }
                Some(c.take(chunk_size))
            } else {
                None
            }
        })
}

用法:

fn main() 
{
    for chunk in chunker(2,[1,2,3,4,5,6].iter()) {
        for n in chunk {
            print!("{},",n);
        }
        print!("\n");
    }
}

输出:

1,6,

上面的算法存在一些效率低下的问题,即克隆迭代器以创建 Take 迭代器,然后独立推进原始迭代器。

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