I have a BTreeMap
where I store items using a two-tuple key, (String, Vec<i32>)
, so the type of map that stores integers is BTreeMap<(String, Vec<i32>), i32>
.
How can I get ranges by using the first element in the two-tuple while ignoring the content of the Vector (alternatively a slice &[i32]
)?
A short example:
//use core::slice::SlicePattern;
use std::collections::BTreeMap;
fn main() {
let mut m : BTreeMap<(String, Vec<i32>), i32> = BTreeMap::new();
m.insert(("hello".to_string(), vec![12]), 34);
m.insert(("hello".to_string(), vec![4]), 56);
m.insert(("other".to_string(), vec![4]), 44);
let res_first = m.get(&("hello".to_string(), vec![12]));
println!("{:?}", res_first);
// not working, and not intuitive range
for (k, v) in m.range(("hello".to_string(), [])..=("g".to_string(), [])) {
println!("key {:?}", k);
}
}
Is there a way I can use a slice pattern or something to make the range query work with Vectors or slices?
or something like:
m.range(("hello".to_string(), [])..=("hello".to_string(), [RangeFull]))
My previous question got a good answer, but it only works for scalars and not Vector or slices.
You can do this much the same way, except that you need a range where the end is exclusive, since you can't (easily) express the maximum possible Vec<i32>
. You can specify an empty Vec
for both ends of the range, and use the next-"largest" string at the end of the range, which is just the same string with a nul character added. (Thanks Filipe for this idea.)
m.range(("hello".to_string(), vec![])..("hello\0".to_string(), vec![]))