Сортировка данных HashMap по значению

Я хочу сортировать данные HashMap по значению в Rust (например, при подсчете частоты символов в строке).

Python эквивалент того, что я пытаюсь сделать:

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])

Мой соответствующий код ржавчины выглядит следующим образом:

// 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);

Является ли эта идиоматическая ржавчина? Могу ли я построить count_vec таким образом, чтобы он использовал данные HashMaps и владел им (например, используя map())? Будет ли это более именованным?

Ответ 1

Является ли эта идиоматическая ржавчина?

Нет ничего особенно унидиотического, кроме, возможно, ненужного полного ограничения типа на count_vec; вы можете просто использовать

let mut count_vec: Vec<_> = count.iter().collect();

Не сложно из контекста выяснить, что такое полный тип count_vec. Вы также можете полностью опустить ограничение типа для count, но тогда вам нужно будет сыграть в shenanigans с вашими целыми литералами, чтобы получить правильный тип значения. То есть, в этом случае явная аннотация чрезвычайно разумна.

Другое изменение границы, которое вы могли бы сделать, если вам кажется, что это будет использовать |a, b| a.1.cmp(b.1).reverse() для закрытия сортировки. Метод Ordering::reverse просто меняет результат так, что меньше, чем становится больше, чем, и наоборот. Это делает несколько более очевидным, что вы имели в виду то, что вы написали, в отличие от случайного переноса двух букв.

Можно ли построить count_vec таким образом, чтобы он использовал данные HashMaps и владел им?

Не имеет смысла. Просто потому, что HashMap использует память, это не означает, что память каким-либо образом совместима с Vec. Вы можете использовать count.into_iter(), чтобы потреблять HashMap и перемещать элементы (в отличие от итерации по указателям), но поскольку как char, так и u32 тривиально можно копировать, это на самом деле ничего не дает вам.