【问题标题】:Rust: BTreeMap equality+inequality range queryRust:BTreeMap 相等+不等范围查询
【发布时间】:2020-02-02 02:35:18
【问题描述】:

我想在 BTreeMap 上调用 range,其中的键是像 (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)。有什么想法吗?

【问题讨论】:

  • 您通常可以使用.. 系列运算符来避免编写ExcludedIncluded。我觉得这更容易阅读。例如,(Excluded((1, 1)), Included((1, 4))) 可以替换为 (1, 1)..=(1, 4),它返回一个 RangeInclusive<(i32, i32)> 类型的对象。

标签: pagination rust range b-tree


【解决方案1】:

如果您的元组的第一个字段是整数类型,那么您可以对下一个整数值使用排他边界,并与空的CStr 配对。 (我假设<&CStr>::default()&CStr 总订单中的“最小”值。)

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

如果第一个字段的类型很难或不可能获得“下一个更大的值”,那么rangetake_while 的组合将给出正确的结果,尽管开销很小。

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

【讨论】:

    猜你喜欢
    • 2022-08-09
    • 2021-09-14
    • 1970-01-01
    • 2017-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-07
    • 2011-03-27
    相关资源
    最近更新 更多