Reversing sort order in Rust
Roman
Posted on November 21, 2023
Rust allows sort items by key easily with .sort_by_key
, here is example, it will put important notes to the end:
#[derive(Debug)]
struct Note {
important: bool,
title: &'static str,
}
let mut notes = vec![
Note { important: false, title: "ddd"},
Note { important: true, title: "aaa"},
Note { important: false, title: "ccc"},
];
notes.sort_by_key(|k| k.important);
println!("{:?}", notes);
But reversing order of sorting with key may be not so obvious, it is achieved with Reverse
helper struct, here is how it can be applied to above example, in order to put important notes first:
use std::cmp::Reverse;
// ...
notes.sort_by_key(|k| Reverse(k.important));
println!("{:?}", notes);
How is it implemented? Let's look at the source code of Rust standard library:
pub struct Reverse<T>(pub T);
impl<T: Ord> Ord for Reverse<T> {
fn cmp(&self, other: &Reverse<T>) -> Ordering {
other.0.cmp(&self.0)
}
}
The implementation is straightforward, it is newtype wrapper for original type, and for types with Ord
trait it reimplements Ord
but instead of comparing self
with other
it comparing other
with self
meaning it will reverse order in the result. Simple and beautiful!
And it will play nicely with complex keys too, lets put important notes first, and sort by title ascending for same importance groups:
notes.sort_by_key(|k| (Reverse(k.important), k.title));
println!("{:?}", notes);
Of course in some cases it is possible to just negate value, like in this example using !k.important
will produce same results, but negating is not always possible (eg. strings). Regarding performance I've benchmarked both methods and have not found any difference, both methods require same time if ordering booleans.
My links
I'm making my perfect todo, note-taking app Heaplist, you can try it here heaplist.app
I have a twitter @rsk
And a website rsk
Posted on November 21, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.