2016-05-08 54 views
1

我有以下功能,這需要一個向量作爲參數,並返回它的對元件中的向量:替代消耗的向量VEC ::塊()

fn to_pairs(flat: Vec<u64>) -> Vec<(u64, u64)> { 
    assert!(flat.len() % 2 == 0); 
    let mut pairs = Vec::new(); 
    pairs.reserve(flat.len()/2); 
    for pair in flat.chunks(2) { 
     assert!(pair.len() == 2); 
     pairs.push((pair.get(0).unwrap().clone(), pair.get(1).unwrap().clone())); 
    } 
    pairs 
} 

我想消耗載體flat所以我在構建這對時不需要克隆它的元素。 如果不自己實現Vec::chunks()的變化,是否可以這樣做?

+0

你想用'unsafe'? – kennytm

+1

我不喜歡。 –

+0

如果您使用其他結構(如[numeric :: Tensor](http://numeric.rs/doc/numeric/tensor/struct.Tensor.html)),它支持重新塑形,它是否合適? – kennytm

回答

0

我想消耗矢量flat所以我不需要在構建對時克隆它的元素。

將輸入Vec轉換爲迭代器,然後從迭代器中一次取兩件事情。從本質上講,你想同樣的事情processing a Range (an iterator) in chunks

fn to_pairs<T>(flat: Vec<T>) -> Vec<(T, T)> { 
    let len = flat.len(); 

    assert!(len % 2 == 0); 
    let mut pairs = Vec::with_capacity(len/2); 

    let mut input = flat.into_iter().peekable(); 

    while input.peek().is_some() { 
     match (input.next(), input.next()) { 
      (Some(a), Some(b)) => pairs.push((a, b)), 
      _ => unreachable!("Cannot have an odd number of values"), 
     } 
    } 

    pairs 
} 

fn main() { 
    assert_eq!(vec![(1,2), (3,4)], to_pairs(vec![1,2,3,4])); 
    assert_eq!(vec![(true,true), (false,false)], to_pairs(vec![true,true,false,false])); 
} 

assert!(len % 2 == 0);是很重要的位置,因爲Iterator不作任何會發生什麼首次next回報None保證。由於我們在不檢查第一個值的情況下調用next兩次,我們可能會觸發該情況。在其他情況下,您需要使用fuse

由於pointed out by Kha,可以簡化while循環了一下:

let mut input = flat.into_iter(); 

while let (Some(a), Some(b)) = (input.next(), input.next()) { 
    pairs.push((a, b)); 
} 
+1

你可以用'(None,None)'代替'peek' –