26 个版本 (11 个稳定)
1.5.1 | 2024年2月27日 |
---|---|
1.4.0 | 2023年9月18日 |
1.3.0 | 2023年1月3日 |
1.2.0 | 2022年12月26日 |
0.1.3 | 2019年2月25日 |
#12 in 数据结构
249,434 每月下载量
在 219 个crate中(36个直接) 使用
215KB
4K SLoC
rangemap
RangeMap
和 RangeInclusiveMap
是以范围为键的映射数据结构。连续和重叠的范围映射到相同的值将合并为单个范围。
还提供了相应的 RangeSet
和 RangeInclusiveSet
结构。
不同类型的范围
RangeMap
和 RangeInclusiveMap
分别对应于标准库中的 Range
和 RangeInclusive
类型。对于某些应用程序,范围类型的选取可能是明显的,甚至可能由现有的设计决策所决定。对于其他应用程序,选取可能似乎是随机的,而是由便利性或审美偏好所指导。
如果您的案例中不明显,请考虑以下差异
- 如果您的密钥类型
K
表示连续体上的点(例如f64
),并且哪个相邻范围“拥有”它们接触的值的选择在很大程度上是任意的,那么使用半开区间Range
(如0.0..1.0
和1.0..2.0
)可能更自然。如果您在这里使用封闭的RangeInclusive
,那么为了表示这两个相邻的范围,您需要从较早的范围的末尾减去一些无穷小值(这可能与f64
的情况一样,取决于K
的具体值)。有关此问题的更多内容,请参阅下面的最后一点。 - 如果您需要表示包含密钥域最大值(例如
255u8
)的范围,那么您可能希望使用RangeInclusive
,如128u8..=255u8
。有时可以通过使用比您实际尝试表示的值更宽的密钥类型(例如K=u16
,尽管您只想表示覆盖u8
的范围)来解决这个问题,但这些情况下密钥域通常代表离散对象,而不是连续体上的点,因此RangeInclusive
可能是表达这些范围的更自然方式。 - 如果您使用
RangeInclusive
,则必须能够为您的密钥类型K
定义 后继 和 前驱 函数,因为不能通过测试它们的端点是否相等来检测相邻范围(从而合并它们)。对于表示连续体上的点的密钥类型,定义这些函数可能很棘手且容易出错。对于表示离散对象的密钥类型,这通常要简单得多。
示例:与 Chrono 一起使用
use chrono::offset::TimeZone;
use chrono::{Duration, Utc};
use rangemap::RangeMap;
fn main() {
let people = ["Alice", "Bob", "Carol"];
let mut roster = RangeMap::new();
// Set up initial roster.
let start_of_roster = Utc.ymd(2019, 1, 7);
let mut week_start = start_of_roster;
for _ in 0..3 {
for person in &people {
let next_week = week_start + Duration::weeks(1);
roster.insert(week_start..next_week, person);
week_start = next_week;
}
}
// Bob is covering Alice's second shift (the fourth shift overall).
let fourth_shift_start = start_of_roster + Duration::weeks(3);
let fourth_shift_end = fourth_shift_start + Duration::weeks(1);
roster.insert(fourth_shift_start..fourth_shift_end, &"Bob");
for (range, person) in roster.iter() {
println!("{} ({}): {}", range.start, range.end - range.start, person);
}
// Output:
// 2019-01-07UTC (P7D): Alice
// 2019-01-14UTC (P7D): Bob
// 2019-01-21UTC (P7D): Carol
// 2019-01-28UTC (P14D): Bob
// 2019-02-11UTC (P7D): Carol
// 2019-02-18UTC (P7D): Alice
// 2019-02-25UTC (P7D): Bob
// 2019-03-04UTC (P7D): Carol
}
软件包功能
默认情况下,此软件包不依赖于其他软件包。
如果您启用 serde1 功能,它将引入对 serde 软件包的依赖,并为该软件包中的所有映射和集合类型提供 Serialize
和 Deserialize
实现。
您可以在 Cargo.toml 文件中这样启用 serde1 功能
[dependencies]
rangemap = { version = "1", features = ["serde1"] }
在没有 Rust 标准库的情况下构建
此软件包可以在没有完整标准库的情况下工作(例如在没有操作系统的裸机运行时),但依赖于全局分配器——即它链接了 core
和 alloc
软件包,但没有 std
。
目前该软件包中没有需要标准库的功能。此类功能可能会在将来引入,并且将受默认启用 std
功能的限制。
有关在没有标准库的情况下操作的一般信息,请参阅《Rust 编程语言》书籍。
依赖项
~165KB