Mutable collection inside a mutable collection?

Let’s say I am generating pairs of random numbers and storing them in a hash map. I’m going to use the first number as the key in a hash map. This will map to a vector of second numbers, because the same first number might appear in multiple pairs.

I think my code should look something like this:

extern crate rand;
use rand::Rng;
use std::collections::HashMap;

fn add_key_value(key: u8, value: u8, hm: &mut HashMap<u8, Vec<u8>>) {
   match hm.get(&key) {
         Some(ref mut v) => {
                 v.push(value);
        },
         _ => {
              let mut v:Vec<u8> = vec![];
              v.push(value);
              hm.insert(key, v);
         },
   }
}

fn main() {
   let mut rng = rand::thread_rng();
   let mut hm:HashMap<u8, Vec<u8>> = HashMap::new();
   for _i in 0..1000 {
       let key:u8 = rng.gen();
       let value:u8 = rng.gen();
       add_key_value(key, value, &mut hm);
   }
   println!("hm = {:?}", hm);
}

This code doesn’t compile:

error[E0596]: cannot borrow `**v` as mutable, as it is behind a `&` reference
 --> src/main.rs:9:4
  |
9 |          v.push(value);
  |          ^ cannot borrow as mutable

How can I fix this? Thank you for your kindness and patience – there are some parts of Rust that are quite odd to an old Objective-C developer.

Aaron

The simplest solution is to change hm.get(&key) by hm.get_mut(&key). I also made a playground with an other solution and some comments (some might be interesting =).

1 Like

I just learned a lot (a lot!) of things from your playground. Thank you so much!