I have a vector [(5, 1), (9, 1), (4, 2)]
I want it to be sorted as [(4, 2), (9, 1), (5, 1)]
Which is sorted in descending order by every second element then the first element.
Would it be possible using sort_by(|x, y| y.cmp(x))
function?
I have a vector [(5, 1), (9, 1), (4, 2)]
I want it to be sorted as [(4, 2), (9, 1), (5, 1)]
Which is sorted in descending order by every second element then the first element.
Would it be possible using sort_by(|x, y| y.cmp(x))
function?
Here is one way to do it:
ve.sort_unstable_by(|a, b| (b.1, b.0).cmp(&(a.1, a.0)));
Note that I used sort_unstable_by()
, which, in your case, would have the same effect as sort_by()
but is a bit faster and uses less memory.
Silvio's suggestion could also be slightly optimized by using sort_unstable_by
:
ve.sort_unstable_by(|x, y| y.1.cmp(&x.1).then(y.0.cmp(&x.0)));
And here is one more way that comes to mind:
ve.sort_unstable_by_key(|k| (-k.1, -k.0));
ve.sort_unstable_by_key(|&(x, y)| Reverse((y, x)))
, using std::cmp::Reverse
. Using negation to sort in reverse order seems like a bit of a hack. –
Fruitcake It is most certainly possible, and you have the right idea using sort_by
. You can sort by the second element in basically the way you suggest.
sort_by(|x, y| y.1.cmp(&x.1))
This solves the first part of your problem. To handle the tiebreaker, we want to be able to say "if the second element is the same, then go by the first element", and in fact Rust has a method that does exactly this: Ordering::then
.
sort_by(|x, y| y.1.cmp(&x.1).then(y.0.cmp(&x.0)))
Note: This will evaluate both orderings in every case, which is probably fine. If your comparison function is unusually expensive, you might consider then_with
instead, which takes a closure rather than a value as its argument.
Copy
types, I'd recommend using v.sort_by_key(|&(_, x)| std::cmp::Reverse(x));
instead, which is clearer. (For non-Copy
types, sort_by_key
has some issues with lifetimes and would be harder to use) –
Cudgel Here is one way to do it:
ve.sort_unstable_by(|a, b| (b.1, b.0).cmp(&(a.1, a.0)));
Note that I used sort_unstable_by()
, which, in your case, would have the same effect as sort_by()
but is a bit faster and uses less memory.
Silvio's suggestion could also be slightly optimized by using sort_unstable_by
:
ve.sort_unstable_by(|x, y| y.1.cmp(&x.1).then(y.0.cmp(&x.0)));
And here is one more way that comes to mind:
ve.sort_unstable_by_key(|k| (-k.1, -k.0));
|a, b| (&b.1, &b.0).cmp(&(&a.1, &a.0))
–
Semasiology ve.sort_unstable_by_key(|&(x, y)| Reverse((y, x)))
, using std::cmp::Reverse
. Using negation to sort in reverse order seems like a bit of a hack. –
Fruitcake © 2022 - 2024 — McMap. All rights reserved.
|a, b| (&b.1, &b.0).cmp(&(&a.1, &a.0))
– Semasiology