How to Sort a Vector in Rust: From Beginner to Pro
Imagine: you are writing a Rust program that collects a list of users — names, ages, ratings. The data comes in a chaotic order. You need to output them alphabetically or, say, sort by age. A familiar task? If you've looked at Stack Overflow, you've probably seen the question "How to sort a vector in Rust?" — it has gathered thousands of views. And this is no coincidence.
Sorting in Rust is one of those topics where "just call sort()" might not work if you don't know a couple of nuances. In this article, we will cover all the popular ways to sort a vector: from the basic sort() method to custom comparators and choosing between stable and unstable sorting. You will learn how to sort a vector in Rust correctly, quickly, and without panic.
Basic Method: sort() — When It's Simple
The simplest way to sort a vector is to use the sort() method. It works for types that implement the Ord trait — which includes all standard primitives (numbers, strings, characters).
fn main() { let mut numbers = vec![4, 2, 9, 1, 5, 6]; numbers.sort(); println!("{:?}", numbers); // Output: [1, 2, 4, 5, 6, 9]}Note: the variable numbers is declared as mut (mutable). The sort() method modifies the vector in place, so without mut the code will not compile. This is a typical beginner mistake — forgetting about mutability.
The same works for strings:
fn main() { let mut fruits = vec!["banana", "apple", "cherry", "date"]; fruits.sort(); println!("{:?}", fruits); // Output: ["apple", "banana", "cherry", "date"]}String sorting by default is lexicographic (alphabetical). If you need sorting by length or ignoring case — see the section on custom comparators.
sort_unstable(): When Speed Matters More Than Order
Rust has two sorting variants: sort() (stable) and sort_unstable() (unstable). The difference is that stable sorting preserves the relative order of equal elements, while unstable sorting does not. This sounds academic, but in practice it matters if you are sorting complex structures and want to preserve the insertion order for equal keys.
However, sort_unstable() has an advantage: it is faster and uses less memory. For large vectors (millions of elements), the difference can be significant.
fn main() { let mut scores = vec![85, 92, 85, 70, 92, 60]; scores.sort_unstable(); println!("{:?}", scores); // Output: [60, 70, 85, 85, 92, 92] // The order of the two 85s and two 92s may differ from the original}When to choose sort_unstable? If you don't care about the order of equal elements and you are optimizing for performance. If predictability is important (e.g., sorting a table with multiple columns), use sort().
sort_by(): Custom Comparators
What to do if you need to sort a vector by a non-standard rule? For example, numbers in descending order, strings by length, or custom structs by one of their fields. For this, there is the sort_by() method, which takes a closure comparator.
The comparator must return Ordering — one of the variants: Less, Equal, or Greater. The simplest way to get such a result is to use the .cmp() or .partial_cmp() methods.
Example: sorting numbers in descending order.
fn main() { let mut numbers = vec![4, 2, 9, 1, 5]; numbers.sort_by(|a, b| b.cmp(a)); println!("{:?}", numbers); // Output: [9, 5, 4, 2, 1]}Note: we swap a and b —