替代使用向量的Vec :: chunks()

时间:2016-05-08 07:34:03

标签: vector iterator rust

我有以下函数,它将vector作为参数并返回其元素对的向量:

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()我自己的变体的情况下这样做?

1 个答案:

答案 0 :(得分:1)

  

我想要使用向量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));
}