[Thiago Cafe] Programming is fun!

## How to sort a vector of a custom struct in Rust

##### Created by Thiago Guedes on 2024-03-08 04:39:59

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.

## Changing the comparing function with a Lambda

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`

## Changing our Lambda to sort in descending order

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!