BTreeSet is Rust's ordered set implementation, backed by a B-tree data structure. Unlike HashSet which stores elements in an arbitrary order, BTreeSet maintains its elements in sorted order according to the Ord trait. This ordering enables powerful range-based operations that are not possible with hash-based sets.
The key advantage of BTreeSet over HashSet is the .range() method, which allows you to efficiently iterate over a subset of elements within a specified range. This is particularly useful for time-based queries (finding events within a date range), numeric filtering (values between min and max), or any scenario where you need to work with ordered subsets of data.
Range queries in Rust use the std::ops::Bound enum to specify inclusive, exclusive, or unbounded endpoints. You can use the convenient range syntax (.., ..=, start..end, etc.) or explicit Bound::Included, Bound::Excluded, and Bound::Unbounded variants for more control.
use std::collections::BTreeSet;
use std::ops::Bound;
let numbers: BTreeSet<i32> = [
1, 3, 5, 7, 9, 11, 13
].into_iter().collect();
// Range from 3 to 9 (exclusive end)
let range: Vec<_> = numbers.range(3..9).copied().collect();
assert_eq!(range, vec![3, 5, 7]);
// Range from 5 to 11 (inclusive end)
let range: Vec<_> = numbers
.range(5..=11)
.copied()
.collect();
assert_eq!(range, vec![5, 7, 9, 11]);
// Everything up to 7 (exclusive)
let range: Vec<_> = numbers.range(..7).copied().collect();
assert_eq!(range, vec![1, 3, 5]);
// Everything from 9 onwards
let range: Vec<_> = numbers.range(9..).copied().collect();
assert_eq!(range, vec![9, 11, 13]);Implement the following functions for working with BTreeSet ranges:
create_number_set(numbers: &[i32]) -> BTreeSet<i32>
get_range( set: &BTreeSet<i32>, start: i32, end: i32 ) -> Vec<i32>
get_range_inclusive( set: &BTreeSet<i32>, start: i32, end: i32 ) -> Vec<i32>
get_elements_before( set: &BTreeSet<i32>, threshold: i32 ) -> Vec<i32>
get_elements_from( set: &BTreeSet<i32>, threshold: i32 ) -> Vec<i32>
count_in_range( set: &BTreeSet<i32>, start: i32, end: i32 ) -> usize
find_closest_less_than( set: &BTreeSet<i32>, value: i32 ) -> Option<i32>
None if no such element exists.find_closest_greater_than( set: &BTreeSet<i32>, value: i32 ) -> Option<i32>
None if no such element exists.use std::collections::BTreeSet;
let set = create_number_set(&[1, 3, 5, 7, 9, 11, 13, 15]);
// get_range: [5, 12) -> 5, 7, 9, 11
assert_eq!(
get_range(&set, 5, 12),
vec![5, 7, 9, 11]
);
// get_range_inclusive: [5, 11] -> 5, 7, 9, 11
assert_eq!(
get_range_inclusive(&set, 5, 11),
vec![5, 7, 9, 11]
);
// get_elements_before: < 7 -> 1, 3, 5
assert_eq!(
get_elements_before(&set, 7),
vec![1, 3, 5]
);
// get_elements_from: >= 9 -> 9, 11, 13, 15
assert_eq!(
get_elements_from(&set, 9),
vec![9, 11, 13, 15]
);
// count_in_range: [3, 11] -> 5 elements (3, 5, 7, 9, 11)
assert_eq!(count_in_range(&set, 3, 11), 5);
// find_closest_less_than: largest element < 10 is 9
assert_eq!(
find_closest_less_than(&set, 10),
Some(9)
);
// find_closest_greater_than: smallest element > 10 is 11
assert_eq!(
find_closest_greater_than(&set, 10),
Some(11)
);.range(start..end) for half-open ranges
and .range(start..=end) for inclusive ranges.copied() or .cloned()
and .collect() the results..threshold or threshold..count_in_range, you can use .range(...).count() directlyfind_closest_less_than, think about
using .range(..value) and getting the last
elementfind_closest_greater_than, think about
using .range((Bound::Excluded(value), Bound::Unbounded))
and getting the first elementBTreeSet::range requires the
bounds to be valid (start <= end for proper
ranges)