按值对HashMap数据进行排序

时间:2016-01-01 11:45:57

标签: rust

我想按Rust中的值对HashMap数据进行排序(例如,在计算字符串中的字符频率时)。

我正在尝试做的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])

我对应的Rust代码如下所示:

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

这是惯用的Rust吗?我是否可以以某种方式构造count_vec以便它使用HashMaps数据并拥有它(例如,使用map())?这会更加自律吗?

2 个答案:

答案 0 :(得分:13)

  

这是惯用的Rust吗?

unidiomatic ,除了可能count_vec上不必要的完整类型约束;你可以使用

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

从上下文中找出完整类型count_vec的内容并不困难。您可以 省略count 完全的类型约束,但是您必须使用整数文字来播放恶作剧才能推断出正确的值类型。也就是说,在这种情况下,显式注释是非常合理的。

其他边界线更改,您可以如果您认为|a, b| a.1.cmp(b.1).reverse()用于排序结束。 Ordering::reverse方法只是反转结果,使得小于大于,反之亦然。这使得意味着你所写的内容更加明显,而不是意外地转换两个字母。

  

我可以以某种方式构造count_vec,以便它使用HashMaps数据并拥有它吗?

没有任何有意义的方式。仅仅因为HashMap使用内存并不意味着内存与Vec完全兼容。您可以使用count.into_iter() 使用 HashMap并移出元素(而不是迭代指针),但由于char和{{1}可以轻易地复制,这对你没什么好处。

答案 1 :(得分:3)

这可能是解决问题的另一种方式,不需要中介媒介。

repository_dispatch