如何在Rust for循环中获取当前迭代中下一次迭代的值?

时间:2017-08-17 08:21:01

标签: for-loop rust

我有一个矢量:

let mut v: Vec<Vec<i32>> = Vec::new();
// [[1, 2, 3], [7, 8, 9], [3, 4, 5], [12, 13, 14], [5, 6, 7]]`

我正在尝试将其排序为:

// [[1, 2, 3], [3, 4, 5], [5, 6, 7], [7, 8, 9], [12, 13, 14]]

我必须通过每个最后一个元素的'continuation'重新组织这个向量向量。重要的是我无法改变向量内元素的位置。我可以改变整个向量的位置。

如何在当前迭代中获取下一次迭代的值?

for n in v {
    temp_current_first = n[0];  // OK
    temp_current_last = n[n.len()-1];  // OK
    temp_next_first = n+1[0]; // It's wrong, but something like this
    temp_next_first = n.next()[0] // or this way ??
}

2 个答案:

答案 0 :(得分:3)

嗯,最简单的解决方案就是:

v.sort();

只会对外部矢量进行排序。否则,如果您想自己实现它,我建议您查看不同的sorting algorithms,因为有许多可能的方法。

答案 1 :(得分:2)

temp_next_first = n+1[0]; // It's wrong, but something like this
temp_next_first = n.next()[0] // or this way ??

这两个不起作用,因为n是一个简单的i32,这意味着它不知道它是v的一部分。

如果您只需要提前一次迭代(在下一个项目中),您可以使用peekable iterator,但因为您必须扫描整个vec,这是不是你需要的。

据我了解你的问题,你想要一种链条,其中一条链的末端与下一条的开头相同。

[4,3][3,7][7,5][5,9] // something like this.

我认为以一种相当快的方式实际执行此操作真的很复杂。 您可以这样做的一种方法如下。

fn order<T: PartialEq>(vec: &mut Vec<(T,T)>) {
    if vec.len() == 0 {
        return;
    }

    let mut temp = vec![vec.remove(0)];

    'outer: loop {
        let mut next: Option<usize> = None;
        'inner: for (i, item) in vec.iter().enumerate() {
            if item.0 == temp.last().unwrap().1 {
                next = Some(i);
                break 'inner;
            }
        }

        match next {
            Some(pos) => temp.push(vec.remove(pos)),
            None => break 'outer,
        }
    }
    *vec = temp;
}

现在你可以这样调用这个函数:

fn main() {
    let mut v: Vec<(i32,i32)> = vec![(4,5),(2,8),(5,7)];

    order(&mut v);

    println!("{:?}",v);
}

这应打印:[(4, 5), (5, 7)]

让我们看看很多中的order函数更多细节:

if vec.is_empty() {
    return;
}

首先我们看看vec是否为空,在这种情况下我们只是退出函数。

let mut temp = vec![vec.remove(0)];

我们创建一个新的Vec<i32,i32>,其中包含我们删除的旧vec的第一个元素。

'outer: loop {
    let mut next: Option<usize> = None;

    /* snip */        

    match next {
        Some(pos) => temp.push(vec.remove(pos)),
        None => break 'outer,
    }
}
*vec = temp;

现在我们创建一个名为Option<usize>的{​​{1}},如果在next循环结束时为零,则'outer内部没有拟合元素,这意味着我们结束此函数并将我们获得的vec设置为Vec

如果tempnext,则表示我们在Some(value)内找到了一个拟合对,然后我们将其移除vecpush。在此之后,我们只需从头开始重复循环。

temp

我们'inner: for (i, item) in vec.iter().enumerate() { if item.0 == temp.last().unwrap().1 { next = Some(i); break 'inner; } } iterate并将vec与最后一个item.0element进行比较,如果这两个相同,我们必须以某种方式删除来自temp的这个element并将其放入vec。遗憾的是,我们无法在temp内变异vec,因为for - 循环引用了for,这意味着我们无法更改vec内部它的。

为避免这种情况,我们只需在vec上致电enumerate(),即告诉我们要移除的vec.iter()的位置。现在,当itemif item.0 == temp.last().unwrap().1时,我们将true设置为nextSome(i)i的位置)并退出{{1}循环。

这应该比它可能应该更详细地解释这个功能,希望它有所帮助。