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.

Original source