Editing Values Of Hashmaps

Here’s a few lines of Python:

numbers = {(0, 0): [], (0, 1): [2], (0, 2): [3]}
numbers[(0, 2)].append(4)

{(0, 0): [], (0, 1): [2], (0, 2): [3, 4]} 

I’m trying to emulate this behavior in Rust with Hashmaps. I am having difficulty adding values to an existing vector. For example:

use std::collections::HashMap;

fn main() {
    let mut numbers: HashMap<(i32, i32), Vec<i32>> = HashMap::new();
    numbers.insert((0, 0), Vec::new());
    numbers.insert((0, 1), vec![2]);
    numbers.insert((0, 2), vec![3]);
    
    numbers[&(0, 2)].push(3) // Fails
}

Any help would be greatly appreciated! I might be using the wrong data type, or maybe there is an existing method to append numbers to the vector. I've tried saving the current vector, appending three to that vector, and inserting the new vector but I always run into some referencing problem.

As the error message indicates, HashMaps don't support mutable indexing for whatever reason. The shortest way I can come up with to do what you want is to use HashMap::entry:

use std::collections::HashMap;

fn main() {
    let mut numbers: HashMap<(i32, i32), Vec<i32>> = HashMap::new();
    numbers.insert((0, 0), Vec::new());
    numbers.insert((0, 1), vec![2]);
    numbers.insert((0, 2), vec![3]);
    
    numbers.entry((0, 2)).and_modify(|v| v.push(3));
    println!("{numbers:?}")
}

Playground link

2 Likes

Fantastic! Works like a charm!!

It actually used to, way back before Rust 1.0, but that led to some confusion around whether indexing should be able to set a value as well as mutate it:

let mut map = HashMap::new();
map["foo"] = 123; // This was a panic, rather than insert!

https://github.com/rust-lang/rust/pull/23559

4 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.