Is there a mutable hashmap?

Hello everybody:

I have this:

        let mut edges_hash: HashMap<i64, HashSet<i64>> = HashMap::new();

when I do this:


          edges_hash[2].insert(3);

I got

trait `IndexMut` is required to modify indexed content, but it is not implemented

What I want to do, if written in c++:

std::unordered_map<int64_t, std::unordered_map<int64_t, int>> edges_hash;

edges_hash[2].insert({3, 3})

I understand HashMap is not mutable. Any mutable alternatives? do I need to use refcell?

Thank you!

Of course it is mutable. You need to do edges_hash.get_mut(&2).unwrap().insert(3);.

HashMap implements Index, but not IndexMut, because it would likely conflict with future language features that don't exist yet and may never, but we still reserve the possibility because it would be nice for map[key] = value to autovivify key in map if it doesn't yet exist (instead of panicking, which is the best possible outcome with IndexMut).

The upshot is, HashMap is mutable, just use get_mut instead of indexing with []. (Since get_mut returns an Option, you will have to handle the None case explicitly.)

2 Likes

Thank you very much!

Notes:

  1. You should read the documentation. How could HashMap not be mutable if there are multiple mutating methods on it, such as insert(), remove(), retain(), etc?

  2. The automatic default-construction in C++'s std::unordered_map has a non-direct but functional and richer equivalent: the Entry API. What you likely want is:

    edges_hash
        .entry(2)
        .or_insert_with(HashSet::new)
        .insert(3);
    
1 Like
edges_hash.entry(2).or_default().insert(3);
1 Like