如何对哈希先按值升序、再按键降序排序?
实现先按数值升序、再按字母逆序的排序方法
当然可以实现你想要的排序效果!你已经找对了方向——sort_by或者sort方法就能搞定,只需要调整排序的判断逻辑就行。
先看你的代码,你已经完成了字符计数的核心部分,接下来只需要在排序环节做针对性调整。这里给你两种可行的实现方式:
方法一:用sort_by(简洁高效)
def letter_counts(word) my_hash = Hash.new(0) word.split("").each { |char| my_hash[char] += 1 } # 核心排序逻辑:先按数值升序,再按字符逆序 my_hash.sort_by { |key, value| [value, -key.ord] } end
逻辑解释:
sort_by会根据块返回的数组来排序:先对比数组的第一个元素(也就是字符出现的次数value),按升序排列;- 当两个元素的
value相等时,会对比第二个元素-key.ord——字符的ASCII码越大,它的负值就越小,负值小的会排在前面,正好实现了字母逆序的效果(比如'r'的ASCII码比'a'大,-r.ord就比-a.ord小,所以'r'会排在'a'前面)。
方法二:用sort(可读性更强)
如果你觉得上面的逻辑有点绕,也可以用sort方法,逻辑更直观:
def letter_counts(word) my_hash = Hash.new(0) word.split("").each { |char| my_hash[char] += 1 } my_hash.sort do |(key1, val1), (key2, val2)| # 第一步:按数值升序比较 val_compare = val1 <=> val2 # 第二步:如果数值相等,按字母逆序比较 val_compare.zero? ? key2 <=> key1 : val_compare end end
逻辑解释:
- Ruby的
<=>(太空船运算符)会返回-1、0或1,用来表示两个值的大小关系; - 先比较两个元素的数值
val1和val2,如果不相等就按升序排列; - 如果数值相等,就用
key2 <=> key1代替key1 <=> key2,这样原本的升序就变成了逆序,正好符合你的需求。
测试这两种方法,都能得到你想要的结果:
[["r", 1], ["k", 1], ["d", 1], ["b", 1], ["a", 1], ["o", 2], ["j", 2], ["f", 2], ["s", 3], ["i", 3]]
内容的提问来源于stack exchange,提问作者Bri Expost
相关产品推荐
相关产品推荐

