首页 > 解决方案 > Rust 的 HashMap 中“插入或更新”操作的最佳实践是什么?

问题描述

我正在寻找一个insert-or-update操作的最佳实践,因为它非常常用,我认为我们需要优化它的写作风格和效率。

假设以下场景:我有一个hashmap

let classes: HashMap(String, HashSet<String>) = HashMap::new()

用于存储学生和谁的班级。

预计数据格式如下:

{ key: "ClassA", value: {"Bob", "Marry", "Jack"}},
{ key: "ClassB", value: {"Lee", "Tom"}},

现在我得到了一个学生和他/她班级的一组新数据,让我们来看看:

{ name: "Alice", class: "ClassC"}

由于我不确定这个类是否已经出现在classesHashMap中,所以我需要先弄清楚它是否存在,如果存在,我将更新值,如果不存在,我将添加一个新key->value对。

没有任何不必要的移动或复制的正确方法是什么?根据其他答案,我尝试使用std::collections::hash_map::Entry但失败了。

谢谢!

标签: rusthashmap

解决方案


使用该地图的惯用方式是这样的:

use std::collections::HashSet;
use std::collections::HashMap;

fn main() {
    let mut classes: HashMap<String, HashSet<String>> = HashMap::new();
    
    let e = classes.entry(String::from("ClassA"));
    e.or_default().insert(String::from("Alice"));

    let e = classes.entry(String::from("ClassA"));
    e.or_default().insert(String::from("Bob"));
    
    dbg!(&classes);
}

HashMap::entry()函数返回一个Entry值,该值表示地图中包含的值或如果它在地图中的位置。这种Entry类型有很多函数可以访问包含的值,并在需要时创建它。在您的情况下,最简单的功能是or_default如果该值尚未在地图中,则创建一个默认值(一个空集)。

然后,由于您对地图内的集合有一个可变引用,因此只需插入所需的值。


推荐阅读