Ordered Collections
range_mut()
The .range_mut(range) method on BTreeMap<K, V> returns a double-ended iterator (std::collections::btree_map::RangeMut<'_, K, V>) that yields (&K, &mut V) pairs for all keys within the specified range, allowing in-place mutation of values across a key subrange in $O(\log n + k)$ time.
Signature and Key Immutability
pub fn range_mut<T, R>(&mut self, range: R) -> RangeMut<'_, K, V>
where
T: Ord + ?Sized,
K: Borrow<T> + Ord,
R: RangeBounds<T>,
Just like .iter_mut(), .range_mut() yields a shared reference to the key (&K) and an exclusive mutable reference to the value (&mut V):
- Mutating
*valin place is completely safe and never rebalances the tree. - Keys cannot be mutated in place because changing a key's sort order would violate the B-Tree invariant. (For
BTreeSet<T>, there is norange_mutmethod because set elements are the keys.)
Updating Values Across a Time or Key Window with range_mut()
use std::collections::BTreeMap;
fn main() {
let mut prices_by_tier = BTreeMap::from([
(1_u8, 100_u32),
(2, 200),
(3, 300),
(4, 400),
(5, 500),
]);
// Apply a +50 surcharge only to mid-level tiers `2..=4`:
for (_tier, price) in prices_by_tier.range_mut(2..=4) {
*price += 50;
}
println!("Updated tiers: {prices_by_tier:?}");
}
Updated tiers: {1: 100, 2: 250, 3: 350, 4: 450, 5: 500}
Modifying Only the First or Last Matching Element in a Range
Because RangeMut implements DoubleEndedIterator, calling .next() or .next_back() on map.range_mut(...) lets you mutate the value of the ceiling ($\ge x$) or floor ($\le x$) key in $O(\log n)$ time:
use std::collections::BTreeMap;
fn main() {
let mut buckets = BTreeMap::from([
(10_u32, vec!["small"]),
(50, vec!["medium"]),
(100, vec!["large"]),
]);
let item_size = 35_u32;
// Find the smallest bucket with capacity >= `item_size` (50) and push to its Vec:
if let Some((&bucket_cap, items)) = buckets.range_mut(item_size..).next() {
items.push("new_item_35");
println!("Placed item of size {item_size} into bucket {bucket_cap}: {items:?}");
}
}
Placed item of size 35 into bucket 50: ["medium", "new_item_35"]