#集合 #集合 # #多重集合 #无std

无std 按集合排序

一个提供编译时配置排序方案的弱排序多重集合库。

4个稳定版本

1.0.3 2022年2月28日

#905数据结构

MIT 许可证

28KB
326

ord-by-set

docs.rs/ord-by-set crates.io 100% documented

一个提供编译时配置排序方案的弱排序多重集合库。

何时使用此库

  • 当你想要一个 BTreeSet,但你的数据涉及部分/松散等价,并且你想要能够高效地检索多个松散等价值时。
  • 当你有与值相同类型的有序键时,允许有内联键的类似 BTreeMap 的数据结构。
    • 这是通过使用自定义的 Order 实现来完成的,以便按照用作键的字段对类型进行排序,而不依赖于完全排序。
  • 当你想要一个多-{集合,映射},但哈希不是一个选项时。

不适用于此

  • 在不需要多个松散等价值时,不要用此库代替 HashMap/HashSet/BTreeMap/BTreeSet

概述

OrdBySet 由两部分组成:其存储后端(一个排序的 Vec<T>)和一个用户提供的排序器。排序器是一个可以接受两个项目并松散比较它们的值。这是通过 Order<T> trait 完成的,它要求一个方法,即 Order::order_of

fn order_of(&self, left: &T, right: &T) -> Ordering;

然而,与 Ord 不同,这并不保证是完全排序的,因此它可以以这种方式使用,将松散等价值分组,类似于如何使用 包数据结构 存储多个相同的值。

然而,不同的特性是,然后可以继续查询所有松散等价类型。排序方案。

[^1]: 一个例子是,你可能希望查询3的结果同时显示整数3和字符串3,同时仍然存储字符串和整数。有关更多信息,请参阅 Order 的文档。

示例

use ord_by_set::OrdBySet;

// Our orderer will be a simple function that sorts based on the first 5 characters
let ordering_fn = |left: &&str, right: &&str| left[..5].cmp(&right[..5]);

let set = OrdBySet::new_with_order(ordering_fn)
    .with_items(["00001_foo", "00001_bar", "00002_foo"]);

let id_1_subset = set.get(&"00001").unwrap();

// id_1_subset = unordered(["00001_foo", "00001_bar"])
assert_eq!(id_1_subset.len(), 2);
assert!(id_1_subset.contains(&"00001_bar"));
assert!(id_1_subset.contains(&"00001_foo"));

虽然上述示例使用闭包作为排序器,但如果你实现了 Order<T>,则可以是任何类型。通常,这通过一个 零大小类型 实现,因为通常排序机制不需要状态,只需要行为。

use ord_by_set::{OrdBySet, Order};
use std::cmp::Ordering;

#[derive(Default)]
struct EverythingEqual;

impl<T> Order<T> for EverythingEqual {
    fn order_of(&self, _: &T, _: &T) -> Ordering {
        Ordering::Equal
    }
}

type AllEqualSet = OrdBySet<i32, EverythingEqual>;

let mut set = AllEqualSet::new().with_items([3, 5, 2, 7]);

assert_eq!(set.count(&30), 4);
set.remove_all(&0);
assert!(set.is_empty());

无运行时依赖