2015-06-13 27 views
3

我试图迭代一个向量作为成对的块(在我的情况下,它是一个图像表示为一个连续的位图,我想访问两行中的像素立刻)。在创建临时向量时迭代成对的块

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

有没有办法纯粹用迭代器呢? (我行如果结果是一个迭代本身)

playpen

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

let tmp : Vec<_> = input.chunks(3).collect(); 
let result : Vec<_> = tmp.chunks(2).collect(); 

[[[0,1,2],[3,4,5]],[[6,1 7,8],[9,10,11]]]

回答

2

哦,我明白了!我可以拆分更大的块:

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

事实上chunk(a).chunk(b)是不可能的,因为chunk()只在一个片可用的,而的chunk()(一个Chunk)的结果不是切片。这太糟糕了,我不知道是什么阻止了在一个普通的Iterator上执行chunk。 (也许是终生问题?)

一个更详细的解决方案,但仍面向迭代器(即不回落到一个丑陋的C++ - 像收集循环)将使用itertools箱,更具体地说是方法batching()。这是从文档的例子,它几乎同样的事情,你chunk(2)除了它返回一个元组,而不是一个切片:

use itertools::Itertools; 

// An adaptor that gathers elements up in pairs 
let pit = (0..4).batching(|mut 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)]); 
+0

我认为使用'Some(x)=>(x,it.next()。unwrap_or(&[]))'应该可以正常工作 - 它处理不均匀的cas e(如果适用)填写空片。 – bluss

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); 
} 
2

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

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]]]