slice::sort¶
Level: reference · for working programmers
One line: Sort in place, ascending, keeping equal elements in their original order.
Stable since 1.0.0.
A stable sort: two elements that compare equal stay in the order they were in. O(n log n), and it may allocate a temporary buffer up to half the slice's length — sort_unstable is the one that promises not to.
It sorts any slice, not only a whole Vec: an array, or a sub-range v[1..4].sort(), because Vec and arrays both deref to [T]. That is why sort is not on the Vec methods list.
T must be Ord. f64 is not — NaN compares to nothing — so floats.sort() is error[E0277]: the trait bound `{float}: Ord` is not satisfied. Use sort_by with f64::total_cmp.
Strings sort by bytes, so every uppercase letter comes before every lowercase one: "Apple" precedes "apple", and "Zoo" precedes "apple" too. Case-insensitive order is a sort_by_key with to_lowercase.
It returns (). let sorted = v.sort(); compiles, binds the unit, and leaves you with no vector — the sort happened to v. For a sorted copy, clone first, or collect from an iterator.
If the Ord implementation is not a total order — a hand-written cmp that is inconsistent with itself — the sort may panic rather than return an arbitrary order. That has been documented since 1.81.
Example¶
slice_sort.rs in full — pasted here by tools/run_examples.py from the file CI compiles and runs.
fn main() {
let mut nums = vec![5, 3, 9, 1, 3];
nums.sort();
println!("{nums:?}");
// Any slice sorts, not just a whole Vec: an array, or a sub-range.
let mut arr = [3, 1, 2];
arr.sort();
let mut part = vec![9, 4, 3, 2, 1, 0];
part[1..4].sort();
println!("{arr:?} {part:?}");
// Strings sort by bytes: every uppercase letter precedes every lowercase one.
let mut words = vec!["pear", "Apple", "fig", "apple", "Zoo"];
words.sort();
println!("{words:?}");
// sort returns (), so binding or printing the result is the trap.
let receipt = nums.sort();
println!("{receipt:?} <- the receipt; nums itself is {nums:?}");
// f64 is not Ord, so `floats.sort()` is error[E0277]. total_cmp is the fix.
let mut floats = vec![2.5, -1.0, 0.0];
// floats.sort();
floats.sort_by(f64::total_cmp);
println!("{floats:?}");
}
Verified output of slice_sort.rs — regenerated by tools/run_examples.py, never hand-typed.
[1, 3, 3, 5, 9]
[1, 2, 3] [9, 2, 3, 4, 1, 0]
["Apple", "Zoo", "apple", "fig", "pear"]
() <- the receipt; nums itself is [1, 3, 3, 5, 9]
[-1.0, 0.0, 2.5]
See also¶
slice::sort_unstable— the same, faster, without the stability promiseslice::sort_by— sort by a comparison you writeslice::sort_by_key— sort by a key you deriveslice::binary_search— what a sorted slice is forslice::reverse— descending, after an ascending sort