Iterator 在不创建临时向量的情况下对块进行迭代

Iterator 在不创建临时向量的情况下对块进行迭代,iterator,rust,Iterator,Rust,我试图将一个向量迭代为成对的块(在我的例子中,它是一个表示为连续位图的图像,我希望能够同时访问两行中的像素) 问题是我不能做.chunks(w).chunks(2),但必须在两者之间创建一个临时向量 有没有一种方法可以完全用迭代器来实现?(如果结果本身是迭代器,我就可以了) let输入:Vec=(0..12).collect(); 让tmp:Vec=input.chunks(3.collect(); let result:Vec=tmp.chunks(2.collect(); 普林顿!(“{:

我试图将一个向量迭代为成对的块(在我的例子中,它是一个表示为连续位图的图像,我希望能够同时访问两行中的像素)

问题是我不能做
.chunks(w).chunks(2)
,但必须在两者之间创建一个临时向量

有没有一种方法可以完全用迭代器来实现?(如果结果本身是迭代器,我就可以了)

let输入:Vec=(0..12).collect();
让tmp:Vec=input.chunks(3.collect();
let result:Vec=tmp.chunks(2.collect();
普林顿!(“{:?}”,结果);
[0,1,2],[3,4,5],[6,7,8],[9,10,11]]

实际上,
chunk(a)。chunk(b)
是不可能的,因为
chunk()
只在一个片上可用,而
chunk()
(a
chunk
)的结果不是一个片。这太糟糕了,我不知道是什么阻止了块在常规的
迭代器上实现。(可能是终身问题?)

一个更详细的解决方案,但仍然是面向迭代器的(即,不要退回到丑陋的C++类收集循环),将是使用板条箱,更具体地说是方法。这是文档中的示例,它的作用与
块(2)
几乎相同,只是它返回一个元组而不是切片:

extern crate itertools;

use itertools::Itertools;

fn main() {
    // An adaptor that gathers elements up in pairs
    let pit = (0..4).batching(|it| match it.next() {
        None => None,
        Some(x) => match it.next() {
            None => None,
            Some(y) => Some((x, y)),
        },
    });

    itertools::assert_equal(pit, vec![(0, 1), (2, 3)]);
}

这是一个创建两个迭代器的解决方案,一个用于奇数行,一个用于偶数行。然后使用
.zip()
组合这两个元素,这将生成一个填充了成对元素的迭代器:

fn main() {
    let input: Vec<_> = (0..12).collect();

    let it1 = input
        .chunks(3)
        .enumerate()
        .filter_map(|x| if x.0 % 2 == 0 { Some(x.1) } else { None });
    let it2 = input
        .chunks(3)
        .enumerate()
        .filter_map(|x| if x.0 % 2 != 0 { Some(x.1) } else { None });

    let r: Vec<_> = it1.zip(it2).collect();

    println!("{:?}", r);
}
fn main(){
让输入:Vec=(0..12).collect();
设it1=输入
.区块(3)
.enumerate()
.filter_map(|x |如果x.0%2==0{Some(x.1)}其他{None});
设it2=输入
.区块(3)
.enumerate()
.filter_map(|x |如果x.0%2!=0{Some(x.1)}其他{None});
让r:Vec=it1.zip(it2.collect();
println!(“{:?}”,r);
}

哦,我找到了!我可以拆分更大的块:

input
   .chunks(2 * 100)
   .map(|pair| pair.split_at(100))

哦,我知道了!我可以拆分更大的块:

input
   .chunks(2 * 100)
   .map(|pair| pair.split_at(100))
input.chunks(2*3).map(| dbl | dbl.split_at(3)).collect()

是的,或者您可以这样做:

let tmp: Vec<_> = input
    .chunks(2 * 3)
    .map(|x| x.chunks(3).collect::<Vec<_>>())
    .collect();
我认为使用
Some(x)=>(x,it.next().unwrap_或(&[])
应该可以很好地工作——它通过填充一个空片段来处理不均匀的情况(如果适用)。