So if I’ve got two vectors:
let mut vec1 = vec![true, false, false, true];
let mut vec2 = vec![1.0, 0.0, 4.0, 2.0];
and I want to sort vec1 and vec2 together according to the floats in vec2, I can zip them together into a tuple and the sort the zipped vector of tuples:
let zipped = vec1.iter().zip(vec2.iter()).collect::<(bool, f64)>();
zipped.sort_by(|a, b| a.1.partial_cmp(&b.1).expect("Can't compare"));
And then I can re-assign the values back to the vectors
vec1 = zipped.iter().map(|z| z.0).collect();
vec2 = zipped.iter().map(|z| z.1).collect();
Is there a more idiomatic way of sorting two parallel vectors in rust? This seems really verbose.
I could put the two items in a struct, but the sorting value is more throw-away than I’d like to associate with a struct all the time, and I feel like creating a wrapper struct to contain the sorting value + original struct is not going to make things any more simple.
Link to playpen, Full code:
fn main() {
let mut vec1: Vec<bool> = vec![true, false, false, true];
let mut vec2: Vec<f64> = vec![1.0, 0.0, 4.0, 2.0];
println!("vec1: {:?}", vec1); // => vec1: [true, false, false, true]
println!("vec2: {:?}", vec2); // => vec2: [1.0, 0.0, 4.0, 2.0]
let mut zipped = vec1
.into_iter()
.zip(vec2.into_iter())
.collect::<Vec<(bool, f64)>>();
zipped.sort_by(|a, b| a.1.partial_cmp(&b.1).expect("Can't compare"));
let vec1_sorted: Vec<bool> = zipped.iter().map(|z| z.0).collect();
let vec2_sorted: Vec<f64> = zipped.iter().map(|z| z.1).collect();
println!("vec1_sorted: {:?}", vec1_sorted); // => vec1_sorted: [false, true, true, false]
println!("vec2_sorted: {:?}", vec2_sorted); // => vec2_sorted: [0.0, 1.0, 2.0, 4.0]
}
>Solution :
There is Iterator::unzip:
let (vec1_sorted, vec2_sorted): (Vec<bool>, Vec<f64>) = zipped.into_iter().unzip();