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.