按值对HashMap数据进行排序

Ste*_*fke 29 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])
Run Code Online (Sandbox Code Playgroud)

我对应的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);
Run Code Online (Sandbox Code Playgroud)

这是惯用的Rust吗?我可以构建count_vec一个方式,以便它会消耗HashMaps数据并拥有它(例如,使用map())?这会更加自律吗?

DK.*_*DK. 20

这是惯用的Rust吗?

除了可能存在不必要的完全类型约束之外,没有什么特别单一的.你可以使用count_vec

let mut count_vec: Vec<_> = count.iter().collect();
Run Code Online (Sandbox Code Playgroud)

从上下文中弄清楚完整类型count_vec是什么并不困难.您也可以count 完全省略类型约束,但是您必须使用整数文字来播放恶作剧,以便推断出正确的值类型.也就是说,在这种情况下,显式注释显然是合理的.

其他边缘改变,你可以做,如果你觉得它是使用|a, b| a.1.cmp(b.1).reverse()的那种封闭.该Ordering::reverse方法只是反转结果,使得小于大于,反之亦然.这使得它稍微明显,你的意思,你写的东西,而不是无意中调换两个字母.

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

没有任何有意义的方式.仅仅因为HashMap使用内存并不意味着内存以任何方式兼容Vec.你可以使用count.into_iter()消耗HashMap和移动的元素了(相对于迭代指针),但由于这两个charu32是平凡可复制,这并不能真正获得你什么.


小智 7

这可能是解决此问题的另一种方式,而无需中介向量。

// 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);
Run Code Online (Sandbox Code Playgroud)


小智 6

用于BTreeMap排序数据

BTreeMap默认情况下对其元素进行排序key,因此交换键和值的位置并将它们放入BTreeMap

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

应该根据字符频率为您提供排序的地图。
但相同频率的某些特征将会丢失。但如果你只想要最常见的字符,那也没关系。

您可以使用得到结果

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