In Rust, how can I get all keys from a HashMap that have a maximum value?
Say I have something like this:
let words = vec!["Hello", "World", "Hello", "everybody", "in", "the", "World"];
let mut word_count = HashMap::new();
for word in words {
let count = word_count.entry(word).or_insert(0);
*count += 1;
}
let max_word = word_count.iter().max_by_key(|entry| entry.1).unwrap().0;
println!("{max_word}");
This only gets me World
, but not Hello
. How can I get both keys in a Vec
?
Related, for a single maximum value: How do I get the key associated with the maximum value of a Rust HashMap?
There are two possible ways:
Loop over the map, maintaining a Vec
of maximum keys and the maximum. If you find something greater, clear the Vec
and update the maximum:
let mut max_keys = Vec::new();
let mut max_value = None;
for (key, value) in &word_count {
match &mut max_value {
None => {
max_keys.push(*key);
max_value = Some(value);
}
Some(max_value) => {
if *max_value < value {
max_keys.clear();
*max_value = value;
}
if *max_value <= value {
max_keys.push(*key);
}
}
}
}
Or just use itertools
' max_set()
, that does this for you:
let max_keys = word_count.iter().max_set_by_key(|(key, value)| *value);
The drawback of this approach is that it requires an allocation.
First find the maximum value, then find all keys with it:
let max_value = word_count.values().copied().max();
let max_keys = max_value.map_or_else(Vec::new, |max_value| {
word_count
.iter()
.filter(|(_key, value)| **value == max_value)
.map(|(key, _value)| *key)
.collect()
});
This approach doesn't require allocations, but it does require two passes on the map.