80. VecDeque::pop_front_if and pop_back_if — Conditional Pops on Both Ends
Vec::pop_if got a deque-shaped sibling. As of Rust 1.93, VecDeque has pop_front_if and pop_back_if — conditional pops on either end without the peek-then-pop dance.
The problem
You want to remove an element from a VecDeque only when it matches a predicate. Before 1.93, you’d peek, match, then pop:
| |
Two lookups, two branches, one opportunity to desynchronize the check from the pop if you refactor the predicate later.
The fix
pop_front_if takes a closure, checks the front element against it, and pops it only if it matches. pop_back_if does the same on the other end.
| |
The return type is Option<T>: Some(value) if the predicate matched and the element was removed, None otherwise (including when the deque is empty).
One subtle detail worth noting — the closure receives &mut T, not &T. That means |&x| won’t type-check; use |x| *x == ... or destructure with |&mut x|. The extra flexibility lets you mutate the element in-place before deciding to pop it.
Draining a prefix
The pattern clicks when you pair it with a while let loop. Drain everything at the front that matches a condition, stop the moment it doesn’t:
| |
No index tracking, no split_off, no collecting into a new deque.
Why both ends?
VecDeque is a double-ended ring buffer, so it’s natural to support the same idiom on both sides. Processing a priority queue from the back, trimming expired entries from the front, popping a sentinel only when it’s still there — all one method call each.
| |
When to reach for it
Whenever the shape of your code is “peek, compare, pop.” That’s the tell. pop_front_if / pop_back_if collapse three steps into one atomic operation, and the Option<T> return makes it composable with while let, ?, and the rest of the Option toolbox.
Stabilized in Rust 1.93 — if your MSRV is recent enough, this is a free readability win.