我正在尝试将一个向量迭代为一对块(在我的例子中,它是一个表示为连续位图的图像,我希望能够同时访问两行中的像素)。
问题是我无法做.chunks(w).chunks(2)
,但必须在两者之间创建一个临时向量。
有没有办法纯粹使用迭代器? (如果结果是迭代器本身,我很好)
let input: Vec<_> = (0..12).collect();
let tmp: Vec<_> = input.chunks(3).collect();
let result: Vec<_> = tmp.chunks(2).collect();
println!("{:?}", result);
[[[0,1,2],[3,4,5]],[[6,7,8],[9,10,11]]]
答案 0 :(得分:5)
哦,我知道了!我可以拆分更大的块:
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();
这与您的示例完全相同,没有您的解决方案中的元组和数组的混合:
[[[0, 1, 2], [3, 4, 5]], [[6, 7, 8], [9, 10, 11]]]
答案 1 :(得分:4)
这是一个创建两个迭代器的解决方案,一个用于奇数行,一个用于偶数行。然后使用.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);
}
答案 2 :(得分:3)
确实chunk(a).chunk(b)
是不可能的,因为chunk()
仅在切片上可用,而chunk()
(a Chunk
)的结果不是切片。这太糟糕了,我不知道是什么阻止了chunk在常规Iterator
上实现。 (也许是终身问题?)
一个更详细的解决方案,但仍然以迭代器为导向(即,不会回到丑陋的C ++ - 如收集循环)将使用itertools包,更具体地说是方法batching()。这是文档中的示例,它与chunk(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)]);
}
答案 3 :(得分:3)
哦,我知道了!我可以拆分更大的块:
input
.chunks(2 * 100)
.map(|pair| pair.split_at(100))