繁体   English   中英

如何使用运行时定义的比较器定义有序的 Map/Set?

[英]How to define an ordered Map/Set with a runtime-defined comparator?

这类似于如何将自定义比较器 function 与 BTreeSet 一起使用? 但是就我而言,直到运行时我才知道排序标准。 可能的标准很广泛,不能硬编码(想想像按目标距离排序或按有效负载中的特定字节或其组合排序)。 创建地图/集后,排序标准不会改变。

我看到的唯一选择是:

  • 使用Vec ,但 log(n) 插入和删除是至关重要的
  • 用排序标准(直接或间接)包装每个元素,但这似乎很浪费

这对于标准 C++ 容器std::map / std::set是可能的,但对于 Rust 的BTreeMap / BTreeSet似乎不可能。 标准库或另一个板条箱中是否有替代方案可以做到这一点? 还是我必须自己实施?


我的用例是一个类似数据库的系统,其中集合中的元素由模式定义,例如:

Element {
    FIELD x: f32
    FIELD y: f32
    FIELD z: i64

    ORDERBY z
}

但是由于模式是在运行时由用户定义的,因此元素存储在一组字节中 ( BTreeSet<Vec<u8>> )。 同样,元素的顺序是用户定义的。 所以我给BTreeSet的比较器看起来像|a, b| schema.cmp(a, b) |a, b| schema.cmp(a, b) 硬编码,上面的例子可能看起来像:

fn cmp(a: &Vec<u8>, b: &Vec<u8>) -> Ordering {
    let a_field = self.get_field(a, 2).as_i64();
    let b_field = self.get_field(b, 2).as_i64();
    a_field.cmp(b_field)
}

是否可以将比较器闭包作为参数传递给需要它的每个节点操作? 它将由树包装器拥有,而不是在每个节点中克隆。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM