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!