Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sorting a vector of tuples needs a reference for the second value?

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.

like image 916
GeckStar Avatar asked Oct 17 '16 16:10

GeckStar


People also ask

How do you sort a vector tuple?

Case 1 : Sorting the vector elements on the basis of first element of tuples in ascending order. This type of sorting can be achieved using simple “ sort() ” function. By default the sort function sorts the vector elements on basis of first element of tuples.

How do you sort the second item in a tuple?

Use the key argument of the sorted() function to sort a list of tuples by the second element, e.g. sorted_list = sorted(list_of_tuples, key=lambda t: t[1]) . The function will return a new list, sorted by the second tuple element.

How do you sort a list of tuples based on two values?

Method #1: Using the Bubble Sort Using the technique of Bubble Sort to we can perform the sorting. Note that each tuple is an element in the given list. Access the second element of each tuple using the nested loops.

How to sort a vector of tuples in C++?

This type of sorting can be achieved using simple “ sort() ” function. By default the sort function sorts the vector elements on basis of first element of tuples. // C++ program to demonstrate sorting in. // vector of tuple according to 1st element.

How to sort a list of tuples based on the second item?

When it is required to sort a list of tuples based on the second item, the lambda function and ‘sorted’ method can be used. A list can be used to store heterogeneous values (i.e data of any data type like integer, floating point, strings, and so on). A list of tuple basically contains tuples enclosed in a list.

What is vector of tuple in Python?

What is Vector of Tuple? A tuple is an object that can hold a number of elements and a vector containing multiple number of such tuple is called a vector of tuple. The elements can be of different data types. The elements of tuples are initialized as arguments in order in which they will be accessed.

How do you sort a list of vector elements?

This type of sorting can be achieved using simple “ sort () ” function. By default the sort function sorts the vector elements on basis of first element of tuples. Case 2 : Sorting the vector elements on the basis of second element of tuples in ascending order.


1 Answers

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);
like image 128
Lukas Kalbertodt Avatar answered Oct 19 '22 12:10

Lukas Kalbertodt