BTreeMap mutable value lookup

So I have a std::BTreeMap. I want to lookup by key and modify the value if present. If the value is not present I'd like to panic (or return Result).

So imediately I looked at std::BTreeMap::entry. But this method returns an std::Entry that, I think, expects to actually modify the collection. The typical use case being this.

myMap.entry(myKey).and_modify(|curr| curr.update()).or_default();

The problem here is the or_default will insert into myMap, I don't want that.

Next I started trying to use get like this, with a modify.

let entry = myMap.get(myKey);
entry.update(); // Can't do this as entry is immutable.

But this returns an immutable entry, cannot be modified, ..... So I've just discovered get_mut which I think might just do the job.

But is there a more idiomatic way in rust to do my initial problem. Insertion seems quite sweet using entry and_modify etc but modification and panic in a single statement seems problematic?

LordLucan

You don't have to use any of the or_* methods on Entry. Instead, you could do something like this:

let Entry::Occupied(value) = myMap.entry(myKey).and_modify(|curr| curr.update()) else {
    panic!("no value found");
}

I'm on my phone, so no code examples. You could use get_mut, or and_modify on the entry, either would work.

1 Like

entry exists because it allows you to handle both the case where the item exists and the case where it doesn't exist with only one lookup. But since you don't need to do anything to the BTreeMap if it doesn't exist, entry isn't useful. Just use get_mut.

1 Like

get_mut is what you want.

fn example(bmap: &mut BTreeMap<i32, String>) {
    bmap.get_mut(&0)
        // panics if value not present
        .expect("0 key missing") 
        .push_str(", world");
}
fn example(bmap: &mut BTreeMap<i32, String>) -> Result<(), &'static str> {
    bmap.get_mut(&0)
        // returns `Err` if value not present
        .ok_or("0 key missing")? 
        .push_str(", world");
        
    Ok(())
}

P.s. wrap your inline code snippets with `...` to make them look like this (and see this post to learn how to post code blocks).

3 Likes

Thank you this technique with the else I've not seen before.

Let-else statements are a relatively new feature, only stabilized in 1.65 in November 2022.

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.