How can I iterate over keys of a HashMap and modify the HashMap itself?

Viewed 96

This is what I'm doing:

struct Foo {
  m: HashMap<u32, String>
}
fn f(foo: &mut Foo) {
  let keys = Vec::new();
  for k in foo.m
    .into_iter()
    .filter(|(k, v)| v > 1)
    .map(|(k, v)| v) { keys.push(k); }
  for k in keys {
    let v = &foo.m.get(k)?;
    // now I do something with v, which in real
    // application is a struct and I will modify it here
  }
}

However, it says something along these lines:

error[E0382]: borrow of moved value: `foo.m`
   --> src/foo.rs:56:24
    |
50  |             .into_iter()
    |              ----------- `foo.m` moved due to this method call
...
56  |             let v = &foo.m.get(k)?;
    |                     ^^^^^^^^^^^^ value borrowed here after move

Basically, I'm trying to take the list of necessary keys and copy this list somewhere. Then, iterate over this new already copied list. What am I doing wrong?

1 Answers

You're probably looking for iter_mut. It allows you to iterate over the entries and modify their values.

Looking at your original implementation, it seems like you only want to modify certain entries and leave others as-is, which is something that can be easily achieved with a guard clause during iteration.

If you want your modified map to also only contain these particular keys, you should consume the full original map using into_iter and filter_map, then collect the tuples into a new map.

Related