使用部分键从HashMap检索值

3

我有一个键类型为(i64,usize)的HashMap。

假设我有一个使用案例,只使用Key元组的第一部分从这个HashMap中检索数据。

例如,我有像这样的示例数据

(-1, 1): "1st -1 Resident", 
(1, 1): "1st 1 Resident", 
(1, 0): "Oth 1 Resident", 
(1, 2): "2nd 1 Resident", 
(-1, 2): "2nd -1 Resident", 
(-1, 0): "Oth -1 Resident"

我想检索或操作所有具有键元组中第一个条目为 -1 的数据。换句话说,对于上面的示例,所有居民的钥匙都是-1

目前我的做法是,循环遍历Hashmap中的所有条目,并手动检查键元组的第一部分。

use std::collections::HashMap;

fn main(){
    let mut hmap: HashMap<(i64,usize), &str> = HashMap::new();
    hmap.insert((-1,0), "Oth -1 Resident");
    hmap.insert((-1,1), "1st -1 Resident");
    hmap.insert((-1,2), "2nd -1 Resident");
    
    hmap.insert((1,0), "Oth 1 Resident");
    hmap.insert((1,1), "1st 1 Resident");
    hmap.insert((1,2), "2nd 1 Resident");

    for (k,v) in &hmap {
        if k.0 == -1 {
            println!("{:?}",v);
        } 
    }
}

有没有更好的方法来处理这个问题? 这是我当前工作的链接(playground link


https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=d89ea0efd40cc1b31c860a0e90e62c43 但是 BTreeMap 是一个有趣的解决方案,看看对于你的用例来说哪个更好。 - Stargateur
1个回答

5
有更好的方法吗?
使用哈希表无法实现部分匹配,因为一个条目是由整个键的哈希定位的。
但是,使用 BTreeMap 可以实现。BTreeMap 的条目基于键的排序而被定位,所以您可以 迭代基于范围的子集, 并且可作为前缀匹配/搜索(这也是为什么例如数据库索引默认使用btrees,它提供比哈希更灵活的查询)。
在这里,您可以请求从 (-1, usize::MIN) 开始并且到 (0, usize::MIN) 结束的范围,它将给出所有键以 -1 开头的条目。

https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=2a78568fa2870afa949919075d7c3579

use std::collections::BTreeMap;

fn main(){
    let mut hmap: BTreeMap<(i64,usize), &str> = BTreeMap::new();
    hmap.insert((-1,0), "Oth -1 Resident");
    hmap.insert((-1,1), "1st -1 Resident");
    hmap.insert((-1,2), "2nd -1 Resident");
    
    hmap.insert((1,0), "Oth 1 Resident");
    hmap.insert((1,1), "1st 1 Resident");
    hmap.insert((1,2), "2nd 1 Resident");

    for (k,v) in hmap.range((-1, usize::MIN)..(0, usize::MIN)) {
        println!("{k:?} {v}");
    }
}

输出:

(-1, 0) Oth -1 Resident
(-1, 1) 1st -1 Resident
(-1, 2) 2nd -1 Resident

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接