HOWTO · Rust
How to Sort a Vector in Rust
Learn how to sort a vector in Rust using the sort() and sort_by() functions, including how to sort floating-point values safely. This guide provides clear examples and explanations to help you master vector sorting in Rust efficiently. Whether you need simple or custom sorting logic, this article covers all the essentials for organizing your data effectively.
On this page
To sort a vector in Rust in ascending order, call sort() on a mutable vector. It changes the vector in place and uses the elements’ natural order. Use sort_by() when you need to compare selected fields or define another ordering. Both methods are provided by Rust’s standard library.
Sort in Place with sort()
sort() is the direct choice when the element type has a natural total order. The vector must be mutable because sorting rearranges its elements. The element type must implement the Ord trait; integers and strings do, while floating-point types do not.
Run this example:
fn main() {
let mut numbers = vec![5, 3, 8, 1, 2];
numbers.sort();
println!("{:?}", numbers);
}
After the call, numbers contains the same values in ascending order. The method sorts the existing vector rather than returning a newly sorted vector, so use the mutable binding when you need to keep the result.
For a vector of strings, sort() uses the type’s natural ordering too. If you need descending order, use sort_by() with the comparison reversed, such as |a, b| b.cmp(a). Choose the ordering deliberately when the natural order does not match how your application presents or groups values.
Use sort_by() for Custom Ordering
sort_by() takes a comparator closure. Rust calls the closure with two elements, and the closure returns an Ordering value: Less, Equal, or Greater. This is a comparison between a pair of elements, rather than a key function that returns one key for each element. The cmp() method on values that implement Ord is a convenient way to produce the result.
This example sorts tuples by their second field, from smallest to largest:
fn main() {
let mut pairs = vec![(1, 3), (2, 1), (3, 2)];
pairs.sort_by(|a, b| a.1.cmp(&b.1));
println!("{:?}", pairs);
}
The closure compares a.1 with b.1; it does not change the tuple values. To sort by multiple fields, compare the primary field first and use another comparison to break ties. Keep the comparator consistent: for a given pair of values, it should express a stable ordering relation. sort_by() also mutates the vector in place, so the same mutable binding rule applies.
Sort Floating-Point Values Safely
Rust’s f32 and f64 types implement PartialOrd, not Ord. Most finite values can be compared, but comparisons involving NaN do not produce an ordering. That is why calling sort() directly on a vector of floats is not available, and why unwrapping partial_cmp() can panic when a value is NaN.
If the desired policy is Rust’s total ordering for floats, use total_cmp() in the comparator. It defines an order that includes NaN and distinguishes negative zero from positive zero. The following self-contained example includes a NaN so the chosen policy is explicit:
fn main() {
let mut values = vec![3.5_f64, f64::NAN, -1.0, 2.0];
values.sort_by(f64::total_cmp);
println!("{:?}", values);
}
total_cmp() is useful when every float must participate in one deterministic order. If your application instead needs all NaN values at the end, or needs to reject them, encode that policy explicitly in the comparator or validate the data before sorting. A total order is a comparison rule; it does not decide which policy is correct for your data.