#100 Apr 24, 2026

100. std::cmp::Reverse — Sort Descending Without Writing a Closure

Want to sort a Vec in descending order? The old trick is v.sort_by(|a, b| b.cmp(a)), and every time you write it you flip a and b and pray you got it right. std::cmp::Reverse is a one-word replacement.

The closure swap trick

To sort descending, you reverse the comparison. The closure is short but easy to mess up:

1
2
3
4
let mut scores = vec![30, 10, 50, 20, 40];
scores.sort_by(|a, b| b.cmp(a));

assert_eq!(scores, [50, 40, 30, 20, 10]);

Swap the a and b and you silently get ascending order again. Not a bug the compiler can help with.

Enter Reverse

std::cmp::Reverse<T> is a tuple wrapper whose Ord impl is the reverse of T’s. Hand it to sort_by_key and you’re done:

1
2
3
4
5
6
use std::cmp::Reverse;

let mut scores = vec![30, 10, 50, 20, 40];
scores.sort_by_key(|&s| Reverse(s));

assert_eq!(scores, [50, 40, 30, 20, 10]);

No chance of flipping the comparison the wrong way — the intent is right there in the name.

Sorting by a field, descending

It really shines when you’re sorting structs by a specific field:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
use std::cmp::Reverse;

#[derive(Debug)]
struct Player {
    name: &'static str,
    score: u32,
}

let mut roster = vec![
    Player { name: "Ferris", score: 42 },
    Player { name: "Corro",  score: 88 },
    Player { name: "Rusty",  score: 65 },
];

roster.sort_by_key(|p| Reverse(p.score));

assert_eq!(roster[0].name, "Corro");
assert_eq!(roster[1].name, "Rusty");
assert_eq!(roster[2].name, "Ferris");

Mixing ascending and descending

Sort by one field ascending and another descending? Pack them in a tuple — Reverse composes cleanly:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
use std::cmp::Reverse;

let mut items = vec![
    ("apple",  3),
    ("banana", 1),
    ("apple",  1),
    ("banana", 3),
];

// Name ascending, then count descending.
items.sort_by_key(|&(name, count)| (name, Reverse(count)));

assert_eq!(items, [
    ("apple",  3),
    ("apple",  1),
    ("banana", 3),
    ("banana", 1),
]);

It works anywhere Ord does

Because Reverse<T> is an Ord type, you can use it with BinaryHeap to turn a max-heap into a min-heap, or with BTreeSet to iterate in reverse order — no extra wrapper types needed.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
use std::cmp::Reverse;
use std::collections::BinaryHeap;

// BinaryHeap is max-heap by default. Wrap in Reverse for min-heap behaviour.
let mut heap = BinaryHeap::new();
heap.push(Reverse(3));
heap.push(Reverse(1));
heap.push(Reverse(2));

assert_eq!(heap.pop(), Some(Reverse(1)));
assert_eq!(heap.pop(), Some(Reverse(2)));
assert_eq!(heap.pop(), Some(Reverse(3)));

When to reach for it

Any time you’d write b.cmp(a) — reach for Reverse instead. The code reads top-to-bottom, the intent is obvious, and there’s no comparator to accidentally flip.

← Previous 99. std::mem::replace — Swap a Value and Keep the Old One