yuwen
yuwen

Reputation: 139

How to change value of a HashMap in a function?

I have a HashMap<u32, u32> like this:

4 -> 1
2 -> 3
5 -> 2

I want to pass it to a function to change its content like this:

4 -> 0
2 -> 2
5 -> 1

i.e., each value is decremented. This is my function:

fn strip_hash(input: &mut HashMap<u32, u32>) -> Vec<u32> {
   let mut result = Vec::new();

   for (k, v) in input {
       if *v > 1 {
           result.push(*k);

           let count = input.entry(*k).or_insert(0);
           *count -= 1;
       }
   }

   result
}

I got the following compiling error:

fn strip_hash(input: &mut HashMap<u32, u32>) -> Vec<u32> {
               ----- move occurs because `input` has type `&mut HashMap<u32, u32>`, which does not implement the `Copy` trait

     for (k, v) in input {
                   ----- `input` moved due to this implicit call to `.into_iter()`

             let count = input.entry(*k).or_insert(0);
                         ^^^^^^^^^^^^^^^ value borrowed here after move

I understand the variable `input' has been moved in "for(k,v) in input" , but how to change the value of HashMap?

Upvotes: 0

Views: 74

Answers (1)

Nikolay Zakirov
Nikolay Zakirov

Reputation: 1584

I am not sure what the Vec return is for so removed it for now:

use std::collections::HashMap;
fn strip_hash(input: &mut HashMap<u32, u32>) {
    // decrement every value in the hashmap by 1
    for (_, v) in input.iter_mut() {
        if *v > 1 {
            *v -= 1;
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_strip_hash() {
        let mut input = HashMap::new();
        input.insert(1, 2);
        input.insert(2, 3);
        input.insert(3, 4);
        strip_hash(&mut input);
        assert_eq!(input.get(&1), Some(&1));
        assert_eq!(input.get(&2), Some(&2));
        assert_eq!(input.get(&3), Some(&3));
    }
}

Upvotes: 1

Related Questions