Tags: #rust
When implementing tags for Texted2, I had a list of tags being:
let tags: Vec<(&str, u32)>; // Tag name, number of posts containing this tag
And I need to sort it by the second item of the tuple, the tag count.
As usual, it was simpler than I expected. This is the code to sort
First: Let's say I want to sort from the smaller count to the larger count
// Adding some types to simplify the reading
freq_list.sort_by(|a: &(&str, u32), b: &(&str, u32)| {
let (_tag_name_a: &&str, count_a: &u32) = a;
let (_tag_name_b: &&str, count_b: &u32) = b;
count_a.cmp(count_b)
});
This is the signature of the method sort_by:
pub fn sort_by<F>(&mut self, mut compare: F)
where
F: FnMut(&T, &T) -> Ordering,
{
stable_sort(self, |a, b| compare(a, b) == Less);
}
And Ordering is an enum with the values Less, Equal and Greater
As the cmp method returns Ordering, to invert the ordering to list the tags from the most common to the least common, it was also quite simple. I just need to invert the Ordering values.
freq_list.sort_by(|a, b| {
let (_tag_name_a, count_a) = a;
let (_tag_name_b, count_b) = b;
match count_a.cmp(count_b) {
Ordering::Less => Ordering::Greater,
Ordering::Equal => Ordering::Equal,
Ordering::Greater => Ordering::Less,
}
});
Note how clear it is that we're changing the order by using a match block.
I hope it is useful to you and reach me out for any comments!