按值对 HashMap 数据进行排序 [英] Sort HashMap data by value

查看:94
本文介绍了按值对 HashMap 数据进行排序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

与我正在尝试做的等效的 Python 是:

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

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

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

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

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?

推荐答案

这是惯用的 Rust 吗?

Is this idiomatic Rust?

没有什么特别的单语,除了可能count_vec的不必要的完整类型约束;你可以使用

There's nothing particularly unidiomatic, except possibly for the unnecessary full type constraint on count_vec; you could just use

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

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

It's not difficult from context to work out what the full type of count_vec is. You could also omit the type constraint for count entirely, but then you'd have to play shenanigans with your integer literals to have the correct value type inferred. That is to say, an explicit annotation is eminently reasonable in this case.

其他你可以做的边界变化是使用|a, b|a.1.cmp(b.1).reverse() 用于排序闭包.Ordering::reverse 方法只是反转结果,使小于变为大于,反之亦然.这使得您意思您所写的内容更加明显,而不是意外地调换了两个字母.

The other borderline change you could make if you feel like it would be to use |a, b| a.1.cmp(b.1).reverse() for the sort closure. The Ordering::reverse method just reverses the result so that less-than becomes greater-than, and vice versa. This makes it slightly more obvious that you meant what you wrote, as opposed to accidentally transposing two letters.

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

Can I construct the count_vec in a way so that it would consume the HashMaps data and owns it?

没有任何意义.仅仅因为 HashMap 使用内存并不意味着内存在任何方面都与 Vec 兼容.您可以使用 count.into_iter()使用 HashMap 并将元素移出(而不是遍历指针),但由于两者charu32 可以简单地复制,这并没有真正给你带来任何好处.

Not in any meaningful way. Just because HashMap is using memory doesn't mean that memory is in any way compatible with Vec. You could use count.into_iter() to consume the HashMap and move the elements out (as opposed to iterating over pointers), but since both char and u32 are trivially copyable, this doesn't really gain you anything.

这篇关于按值对 HashMap 数据进行排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆