简体   繁体   中英

How to get value of next iteration in current iteration in Rust for loop?

I have a vector:

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

I'm trying to sort it to:

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

I have to reorganize this vector of vectors by the 'continuation' of each last element. The important thing is I can't change position of elements inside vectors. I can change positions of only whole vectors.

How can I get the value of the next iteration in current iteration?

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 ??
}

Well, the simplest solution would be to just do:

v.sort();

Which will only sort the outer vector. Otherwise, if you would like to implement it yourself, I would suggest looking at different sorting algorithms , as there are many possible ways of doing it.

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

those 2 don't work because n is a simple i32 , meaning that it does not know that it is part of v .


In case you only need to look one iteration ahead (at the next item) , you could use a peekable iterator , but because you have to scan through the whole vec, this is not what you need here.


As far as I understand your question you want to have a kind of chain where one the end of one piece is the same as the start of the next.

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

I think that it is really complicated to actually do this in a rather quick way. One way you could do this is the following.

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

Now you could call this function like this:

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

    order(&mut v);

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

This should print: [(4, 5), (5, 7)]


Let's look at the order function in a lot more detail:

if vec.is_empty() {
    return;
}

First we see if vec is empty, in this case we just exit the function.

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

We create a new Vec<i32,i32> which contains the first element of the old vec, which we remove.

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

    /* snip */        

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

Now we create an Option<usize> called next , if this is zero at the end of the 'outer loop, there was no fitting element inside of vec meaning that we end this function and set the Vec we got as input to temp .

If next is Some(value) , it means that we found a fitting pair inside of vec which we then remove and push into temp . After this we just repeat start the loop from the beginning.

'inner: for (i, item) in vec.iter().enumerate() {
    if item.0 == temp.last().unwrap().1 {
        next = Some(i);
        break 'inner;
    }
}

Here we iterate through vec and compare item.0 to the last element or temp , in case these two are the same we have to somehow remove this element from vec and put it into temp . Sadly we can not mutate vec inside of for , because the for -loop has a reference to vec , meaning that we can't change vec inside of it.

To circumvent this we simply call enumerate() on our vec.iter() this tells us the position of the item we want to remove. Now, when if item.0 == temp.last().unwrap().1 is true , we set next to Some(i) ( i is the position of item ) and exit the 'inner loop.

This should explain the function in far more detail than it probably should, hope it helps somehow.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM