У меня есть BTreeMap
, где я храню элементы с помощью двухкортежного ключа (String, i32)
, поэтому типом карты, в которой хранятся целые числа, является BTreeMap<(String, i32), i32>
.
Есть ли способ найти элементы, используя первый элемент двухкортежа? Например. какая-то форма пользовательского диапазона? Как бы я это сделал?
Краткий пример:
use std::collections::BTreeMap;
fn main() {
let mut m : BTreeMap<(String, i32), i32> = BTreeMap::new();
m.insert(("hello".to_string(), 12), 34);
m.insert(("hello".to_string(), 4), 56);
m.insert(("other".to_string(), 4), 44);
let one_element = m.get(&("hello".to_string(), 12));
println!("{:?}", one_element);
// does not work, perhaps some custom range could be used?
let all_hello = m.get(&("hello".to_string(), _));
}
Вы можете использовать BTreeMap::range для этого:
let range = m.range(("hello".to_string(), i32::MIN)..=("hello".to_string(), i32::MAX));
for item in range {
println!("{:?}", item);
}
Обратите внимание: из-за особенностей работы признака Borrow
вам, к сожалению, придется выделить две строки, по одной для каждого конца диапазона.
Нет, в этом случае самым простым, вероятно, было бы использовать полуоткрытый диапазон и следующее значение для первой части ключа, например. "g".to_string()
(и в качестве второй части можно использовать пустой век, не имеет значения). В качестве альтернативы — и это тоже довольно распространено — просто не устанавливайте верхнюю границу диапазона и останавливайтесь динамически, например. используя адаптер итератора take_while
.
@Masklinn Я создал еще один вопрос для диапазонов векторов/срезов stackoverflow.com/questions/78583177/…
Хороший трюк, используйте
i32::MIN
иi32::MAX
. Есть ли какой-нибудь соответствующий трюк дляVec<i32>
илиVec<_>
, чтобы второй элемент в двухкортеже мог быть любым Vector ? Альтернатива кусочку?