Sorting a vector of tuples needs a reference for the second value?
reference, rust, sorting, tuples, vector
Solution
As Aurora0001 already pointed out in the comments, we should have a look at the function signature of `cmp()`:
fn cmp(&self, other: &Self) -> Ordering
We see that both values are taken by reference, so it shouldn't be a surprise that you have to pass `&b.1` to the method instead of `b.1`.
Especially because I do not need to reference `a.1`, either.
This is the more interesting question ;-)
The simple solution is, that the `.` (dot) operator performs auto-dereferencing as well as auto-borrowing. Let's see it in action:
struct Foo;
impl Foo {
fn takes_value(self) {}
fn takes_ref(&self) {}
fn takes_mut_ref(&mut self) {}
}
fn main() {
let mut a = Foo;
// all of those work thanks to auto-borrowing
a.takes_ref();
a.takes_mut_ref();
a.takes_value();
// --------
let b = Foo;
let c = &mut b;
// these work as well
c.takes_ref();
c.takes_mut_ref();
// this one works, *if* the type implements `Copy`
c.takes_value();
}
So the `.` operator helps the programmer and always passes the right kind of `self` parameter.
Note: the kind of sorting you are doing very common. There is a method even better suited for this task: `[T]::sort_by_key()`. It would look like this:
// note: type annotations not required
let mut tuple_list2 = vec![(1, 5), (0, 17), (8, 2)];
tuple_list2.sort_by_key(|k| k.1);
Problem
I have a vector of tuples of integers and want to sort it by the second element of each tuple: ``` fn main() { let mut tuple_list2: Vec<(u16, u16)> = vec![(1, 5), (0, 17), (8, 2)]; tuple_list2.sort_by(|a, b| a.1.cmp(b.1)); } ``` The compiler throws an error because `b.1` is a `u16` and not a reference to one (`&u16`). I can solve this problem by referencing `b.1` instead: ``` fn main() { let mut tuple_list2: Vec<(u16, u16)> = vec![(1, 5), (0, 17), (8, 2)]; tuple_list2.sort_by(|a, b| a.1.cmp(&b.1)); } ``` I don't understand why I have to do this. Especially because I do not need to reference `a.1`, either.