簡體   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