How can I update a value in a mutable HashMap?

后端 未结 3 1310
我寻月下人不归
我寻月下人不归 2020-11-28 10:46

Here is what I am trying to do:

use std::collections::HashMap;

fn main() {
    let mut my_map = HashMap::new();
    my_map.insert(\"a\", 1);
    my_map.inse         


        
相关标签:
3条回答
  • Considering:

    let mut m = std::collections::HashMap::new();
    m.insert("a", 1);
    m.insert("b", 3);
    let k = "c";
    

    If the key already exists:

        m.insert(k, 10 + m[k] );
    

    If the key not exists:

    1. You may update a value of the key:
        m.insert(k, 10 + if m.contains_key(k) { m[k] } else { 0 });
    
    1. Or first insert a key only if it doesn't already exist:
        m.entry(k).or_insert(0);
        m.insert(k, 200 + m[k]);
    
    1. Or update a key, guarding against the key possibly not being set:
        *m.entry(k).or_insert(0) += 3000;
    

    Finally print the value:

        println!("{}", m[k]); // 3210
    

    See:
    https://doc.rust-lang.org/std/collections/struct.HashMap.html

    0 讨论(0)
  • 2020-11-28 11:28

    I will share my own Answer because I had this issue but I was working with Structs so, that way in my case was a little bit tricky

    use std::collections::HashMap;
    
    #[derive(Debug)]
    struct ExampleStruct {
        pub field1: usize,
        pub field2: f64,
    }
    
    fn main() {
        let mut example_map = HashMap::new();
        &example_map.insert(1usize, ExampleStruct { field1: 50, field2: 184.0});
        &example_map.insert(6usize, ExampleStruct { field1: 60, field2: 486.0});
    
        //First Try
        (*example_map.get_mut(&1).unwrap()).field1 += 55; //50+55=105
        (*example_map.get_mut(&6).unwrap()).field1 -= 25; //60-25=35
    
        //Spliting lines
        let op_elem = example_map.get_mut(&6);
        let elem = op_elem.unwrap();
        (*elem).field2 = 200.0;
    
        let op_ok_elem = example_map.get_mut(&1);
        let elem = op_ok_elem.unwrap_or_else(|| panic!("This msg should not appear"));
        (*elem).field2 = 777.0;
    
        println!("Map at this point: {:?}", example_map);
        let op_err_elem = example_map.get_mut(&8);
        let _elem = op_err_elem.unwrap_or_else(|| panic!("Be careful, check you key"));
    
        println!("{:?}", example_map);
    }
    

    You can play with this on Rust Playground

    0 讨论(0)
  • 2020-11-28 11:30

    Indexing immutably and indexing mutably are provided by two different traits: Index and IndexMut, respectively.

    Currently, HashMap does not implement IndexMut, while Vec does.

    The commit that removed HashMap's IndexMut implementation states:

    This commit removes the IndexMut impls on HashMap and BTreeMap, in order to future-proof the API against the eventual inclusion of an IndexSet trait.

    It's my understanding that a hypothetical IndexSet trait would allow you to assign brand-new values to a HashMap, and not just read or mutate existing entries:

    let mut map = HashMap::new();
    map["key"] = "value";
    

    For now, you can use get_mut:

    *my_map.get_mut("a").unwrap() += 10;
    

    Or the entry API:

    *my_map.entry("a").or_insert(42) += 10;
    
    0 讨论(0)
提交回复
热议问题