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.
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.
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.
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.
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.
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? 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.
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.
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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With