I have two HashMap
s that will always be the same size (always the same keys, different values). I want to copy the values from the one HashMap
to another. Is there a nice way to do this without reallocating a new HashMap
?
You can iterate over first HashMap and write the values to the other, you don't need to allocate a temporary HashMap or reallocate the second one if it's capacity is enough.
I think I basically just want an .update()
method?
let map1: HashMap<_, _> = // large hashmap contents
let mut map2: HashMap<_, _> = // large hashmap contents
map2.update(&map1).
Currently I'm just cloning the first map, and dropping the previous one. So I was wondering if there was a better use of memory than the following.
map2 = map1.clone()
use std::collections::HashMap;
fn main() {
let map1: HashMap<i32, i32> = HashMap::new(); // large hashmap contents
let mut map2: HashMap<i32, i32> = HashMap::new(); // large hashmap contents
// overwrite map2 with the contents of map1
map2.clear();
map2.extend(map1.into_iter());
// `map1.into_iter()` consumes map1 and turns it into an iterator
}
You can also write this as:
map2.extend(map1);
If you need to keep map1
around, you can do:
map2.extend(map1.iter().cloned());
This will clone each item in map1
but it will not clone the HashMap
itself.
Thanks! This is exactly what I want. Must have missed it in the docs.
You could also use the often forgotten Clone::clone_from
, so it would just be map2.clone_from(&map1)
This won’t work. The map’s iterator is over (&K, &V)
, so .cloned()
does not apply.
For your setting where your target map already has all the keys, you can avoid needing to re-create all the keys again, whereas both
map2.extend(map1.iter().map(|(k,v)| (k.clone(), v.clone())))
and
map2.clone_from(&map1)
will have to clone every key.
When all the necessary keys are already present, you can work with something like e.g.:
fn try_update_map<K: Eq + Hash, V: Clone>(target: &mut HashMap<K, V>, source: &HashMap<K, V>) -> Option<()> {
source.iter().try_for_each(|(k, v)| Some(*target.get_mut(k)? = v.clone()))
}
or
fn update_map<K: Eq + Hash, V: Clone>(target: &mut HashMap<K, V>, source: &HashMap<K, V>) {
source.iter().for_each(|(k, v)| *target.get_mut(k).unwrap() = v.clone())
}
This is probably strictly more performant than anything involving .extend
. The .clone_from
version could be better when cloning keys is cheap. I’m just guessing though.
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.