'Sort HashMap data by value

I want to sort HashMap data by value in Rust (e.g., when counting character frequency in a string).

The Python equivalent of what I’m trying to do is:

count = {}
for c in text:
    count[c] = count.get('c', 0) + 1

sorted_data = sorted(count.items(), key=lambda item: -item[1])

print('Most frequent character in text:', sorted_data[0][0])

My corresponding Rust code looks like this:

// Count the frequency of each letter
let mut count: HashMap<char, u32> = HashMap::new();
for c in text.to_lowercase().chars() {
    *count.entry(c).or_insert(0) += 1;
}

// Get a sorted (by field 0 ("count") in reversed order) list of the
// most frequently used characters:
let mut count_vec: Vec<(&char, &u32)> = count.iter().collect();
count_vec.sort_by(|a, b| b.1.cmp(a.1));

println!("Most frequent character in text: {}", count_vec[0].0);

Is this idiomatic Rust? Can I construct the count_vec in a way so that it would consume the HashMaps data and owns it (e.g., using map())? Would this be more idomatic?



Solution 1:[1]

This could be another way to address the matter without the need of an intermediary vector.

// Count the frequency of each letter
let mut count: HashMap<char, u32> = HashMap::new();
for c in text.to_lowercase().chars() {
    *count.entry(c).or_insert(0) += 1;
}

let top_char = count.iter().max_by(|a, b| a.1.cmp(&b.1)).unwrap();

println!("Most frequent character in text: {}", top_char.0);

Solution 2:[2]

use BTreeMap for sorted data

BTreeMap sorts its elements by key by default, therefore exchanging the place of your key and value and putting them into a BTreeMap

let count_b: BTreeMap<&u32,&char> = count.iter().map(|(k,v)| (v,k)).collect();

should give you a sorted map according to character frequency.
Some character of the same frequency shall be lost though. But if you only want the most frequent character, it does not matter.

You can get the result using

println!("Most frequent character in text: {}", count_b.last_key_value().unwrap().1);

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Juan Vidal
Solution 2 StevenHe