Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's an idiomatic way to delete a value from HashMap if it is empty?

Tags:

rust

The following code works, but it doesn't look nice as the definition of is_empty is too far away from the usage.

fn remove(&mut self, index: I, primary_key: &Rc<K>) {
    let is_empty;
    {
        let ks = self.data.get_mut(&index).unwrap();
        ks.remove(primary_key);
        is_empty = ks.is_empty();
    }
    // I have to wrap `ks` in an inner scope so that we can borrow `data` mutably.
    if is_empty {
        self.data.remove(&index);
    }
}

Do we have some ways to drop the variables in condition before entering the if branches, e.g.

if {ks.is_empty()} {
    self.data.remove(&index);
}
like image 358
colinfang Avatar asked May 10 '17 12:05

colinfang


1 Answers

Whenever you have a double look-up of a key, you need to think Entry API.

With the entry API, you get a handle to a key-value pair and can:

  • read the key,
  • read/modify the value,
  • remove the entry entirely (getting the key and value back).

It's extremely powerful.

In this case:

use std::collections::HashMap;
use std::collections::hash_map::Entry;

fn remove(hm: &mut HashMap<i32, String>, index: i32) {
    if let Entry::Occupied(o) = hm.entry(index) {
        if o.get().is_empty() {
            o.remove_entry();
        }
    }
}

fn main() {
    let mut hm = HashMap::new();
    hm.insert(1, String::from(""));

    remove(&mut hm, 1);

    println!("{:?}", hm);
}
like image 147
Matthieu M. Avatar answered Nov 11 '22 21:11

Matthieu M.