In Rust, how do I create a HashSet from the keys of a HashMap?
The simple solution
Your code only needs a few tweaks to actually compile (see Playground):
use std::collections::{HashSet, HashMap};
fn main() {
let mut map1 = HashMap::new();
let mut map2 = HashMap::new();
// Add some values into the HashMaps for demonstration
map1.insert(1, 10);
map1.insert(5, 50);
map2.insert(3, 30);
map2.insert(5, 50);
let set1: HashSet<i64> = map1.keys().cloned().collect();
let set2: HashSet<i64> = map2.keys().cloned().collect();
let set3 = set1.intersection(&set2);
println!("{:?}", set3);
}
In particular, note map1.keys().cloned().collect()
:
HashMap<K, V>::keys()
returns anIterator<Item = &'a K>
,.cloned()
transforms that to anIterator<Item = K>
,.collect()
builds a collection from that, sinceHashSet
implements theFromIterator
trait.
However, this is not very efficient:
- Complexity wise:
O(map1.size() + map2.size())
. - Memory wise: potentially large allocations.
The efficient solution
Implement intersection
directly on the keys of HashMap
.
You just need to collect into the HashSet
:
let set1: HashSet<i64> = map1.keys().copied().collect();
let set2: HashSet<i64> = map2.keys().copied().collect();
Using copied()
will dereference the keys and copy them, since you want a HashSet<i64>
not a HashSet<&i64>