0

I have a HashMap<String, Vec<String>>. After removing an element from a vector, I want to remove this vector's entry if it is empty. I've tried to do this:

use std::collections::HashMap;

fn main() {
    let mut map: HashMap<String, Vec<String>> = HashMap::new();

    map.insert(String::from("key"), vec![String::from("value")]);

    let a_key = String::from("key");
    let del_from_vec = String::from("value");

    match map.get_mut(&a_key) {
        Some(vect) => match vect.binary_search(&del_from_vec.to_string()) {
            Ok(index) => {
                vect.remove(index);
                println!("value removed from vector.");
                if vect.len() == 0 {
                    map.remove(&a_key);
                    println!("entry removed from map.");
                }
            }
            Err(_) => println!("not found in vec."),
        },
        None => println!("no such key in map."),
    }
}

The compiler complains about this:

error[E0499]: cannot borrow `map` as mutable more than once at a time
  --> src/main.rs:17:21
   |
11 |     match map.get_mut(&a_key) {
   |           --- first mutable borrow occurs here
...
17 |                     map.remove(&a_key);
   |                     ^^^ second mutable borrow occurs here
...
24 |     }
   |     - first borrow ends here

I fully understand the error. I can overcome it by doing this:

use std::collections::HashMap;

fn main() {
    let mut map: HashMap<String, Vec<String>> = HashMap::new();

    map.insert(String::from("key"), vec![String::from("value")]);

    let a_key = String::from("key");
    let del_from_vec = String::from("value");

    if map.contains_key(&a_key) {
        match map[&a_key].binary_search(&del_from_vec.to_string()) {
            Ok(index) => {
                map.get_mut(&a_key).unwrap().remove(index);
                println!("value removed from vector.");
                if map[&a_key].len() == 0 {
                    map.remove(&a_key);
                    println!("entry removed from map.");
                }
            }
            Err(_) => println!("not found in vec."),
        }
    }
}

I find this code kind of ugly because it uses contains_key() and unwrap(). How else could I write this?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
  • You can't. [At least not until non-lexical lifetimes are stabilized](https://play.rust-lang.org/?gist=b4060563828111c1561b13aee68d597f&version=nightly). – Shepmaster Feb 04 '18 at 02:57
  • @Shepmaster, I don't see my question as a duplicate of the one you pointed out, but I understand the cause for both is the same, so thanks for pointing it out. May I ask you why you changed the commas in the code? – Douglas Santos Feb 04 '18 at 04:17
  • I reformat all code in questions and answers using rustfmt so that people looking for answers don't have to adapt to every posters specific formatting. Rustfmt removes commas around march arms with braces and adds them to trailing arms. – Shepmaster Feb 04 '18 at 04:21

0 Answers0