Rust: BTreeMap равенство + запрос диапазона неравенства - PullRequest
1 голос
/ 03 октября 2019

Я хочу позвонить range на BTreeMap, где ключи являются кортежами типа (a,b). Скажем, у нас есть:

  • (1, 2) => "a"
  • (1, 3) => "b"
  • (1, 4) => "c"
  • (2, 1) => "d"
  • (2, 2) => "e"
  • (2, 3) => "f"

Особенность в том, что мне нужны все записи, которые имеют определенное значение для первого поля, но диапазон во втором поле, т.е. я хочувсе записи где a = 1 AND 1 < b <= 4. Оператор RangeBounds в этом случае не слишком сложен, это будет (Excluded((1, 1)), Included((1, 4))). Если бы у меня был неограниченный диапазон, скажем, a = 1 AND b > 3, у нас было бы следующее RangeBounds: (Excluded((1, 3)), Included((1, i64::max_value()))).

Проблема возникает, когда тип внутри кортежа не имеет максимального значения, например строка (особенно CStr). Есть ли способ решить эту проблему? Было бы полезно иметь возможность использовать Unbounded внутри кортежа, но я не думаю, что это правильно. Менее интересным решением было бы иметь несколько слоев структур данных (например, хеш-карту для первого поля, где ключи отображаются на ... BTreeMap). есть идеи?

1 Ответ

2 голосов
/ 04 октября 2019

Если первое поле вашего кортежа является целочисленным типом, то вы можете использовать исключительную границу для следующего целочисленного значения в паре с пустым CStr. (Я предполагаю, что <&CStr>::default() является «наименьшим» значением в общем порядке &CStr.)

let range = my_btree_map.range((Excluded((1, some_cstr)), Excluded((2, <&CStr>::default()))));

Если первое поле относится к типу, для которого трудно или невозможнополучить «следующее большее значение», тогда комбинация range и take_while даст правильные результаты, хотя и с небольшими накладными расходами.

let range = my_btree_map
    .range((Excluded((1, some_cstr)), Unbounded))
    .take_while(|&((i, _), _)| *i == 1);
...