我想按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和移动的元素了(相对于迭代指针),但由于这两个char和u32是平凡可复制,这并不能真正获得你什么.
小智 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)