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()
(achunk
)的结果不是一个片。这太糟糕了,我不知道是什么阻止了块在常规的迭代器上实现。(可能是终身问题?)
一个更详细的解决方案,但仍然是面向迭代器的(即,不要退回到丑陋的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_或(&[])
应该可以很好地工作——它通过填充一个空片段来处理不均匀的情况(如果适用)。