What's the idiomatic way to remove a value from a HashMap if it's empty?

The following code works, but it doesn't look as good as the definition is is_empty

too far from being used.

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 discard variables in the state before entering if branches, for example.

if {ks.is_empty()} {
    self.data.remove(&index);
}

      

+3


source to share


2 answers


Whenever you have a double lookup for a key, you need to think about the login API .

From the login API, you get a handle to a key-value pair and can:

  • read the key,
  • read / change value,
  • delete the entry completely (get the key and value back).


It is very 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);
}

      

+7


source


I did this at the end:



match self.data.entry(index) {
    Occupied(mut occupied) => {
        let is_empty = {
            let ks = occupied.get_mut();
            ks.remove(primary_key);
            ks.is_empty()
        };
        if is_empty {
            occupied.remove();
        }

    },
    Vacant(_) => unreachable!()
}

      

+1


source







All Articles