首先在Ruby中按哈希值对其哈希值进行排序

我试图根据单词出现的次数对文档进行排序,然后按字母顺序排列,所以输出时看起来就像这样。

Unsorted: 'the', '6' 'we', '7' 'those', '5' 'have', '3' Sorted: 'we', '7' 'the', '6' 'those', '5' 'have', '3' 

试试这个:

假设:

 a = { 'the' => '6', 'we' => '7', 'those' => '5', 'have' => '3', 'hav' => '3', 'haven' => '3' } 

然后这样做:

 b = a.sort_by { |x, y| [ -Integer(y), x ] } 

b将如下所示:

 [ ["we", "7"], ["the", "6"], ["those", "5"], ["hav", "3"], ["have", "3"], ["haven", "3"] ] 

编辑按反向频率排序。

 words = {'the' => 6,'we' => 7,'those' => 5,'have' => 3} sorted_words = words.sort { |a,b| b.last <=> a.last } sorted_words.each { |k,v| puts "#{k} #{v}"} 

生产:

 we 7 the 6 those 5 have 3 

您可能希望值​​为整数而不是字符串以进行比较。

编辑

糟糕,忽略了需要按键排序的要求。 所以:

 words = {'the' => 6,'we' => 7,'those' => 5,'have' => 3,'zoo' => 3,'foo' => 3} sorted_words = words.sort do |a,b| a.last == b.last ? a.first <=> b.first : b.last <=> a.last end sorted_words.each { |k,v| puts "#{k} #{v}"} 

生产:

 we 7 the 6 those 5 foo 3 have 3 zoo 3 

在散列上使用sort方法时,在比较块中会收到两个元素数组,您可以使用它们在一次传递中进行比较。

 hsh = { 'the' => '6', 'we' => '6', 'those' => '5', 'have' => '3'} ary = hsh.sort do |a,b| # a and b are two element arrays in the format [key,value] value_comparison = a.last <=> b.last if value_comparison.zero? # compare keys if values are equal a.first <=> b.first else value_comparison end end # => [['have',3],['those',5],['the',6],['we',6]] 

请注意,结果是一个数组数组,因为哈希在ruby中没有内在顺序

试试这个:

 words = {'the' => 6,'we' => 7,'those' => 5,'have' => 3} words.sort { |(x_k, x_v), (y_k, y_v)| [y_v, y_k] <=> [x_v, x_k]} #=> [["we", 7], ["the", 6], ["those", 5], ["have", 3]] 
 histogram = { 'the' => 6, 'we' => 7, 'those' => 5, 'have' => 3, 'and' => 6 } Hash[histogram.sort_by {|word, freq| [-freq, word] }] # { # 'we' => 7, # 'and' => 6, # 'the' => 6, # 'those' => 5, # 'have' => 3 # } 

注意:这假设您使用数字来存储数字。 在您的数据模型中,您似乎使用字符串来存储数字。 我不知道你为什么要这样做,但如果你想这样做,你显然必须在排序之前将它们转换为数字,然后再转换回字符串。

此外,这假设Ruby 1.9。 在Ruby 1.8中,哈希不是有序的,因此您无法将排序后的结果转换回哈希,因为这会丢失排序信息,您必须将其保留为数组。

1.9.1

 >> words = {'the' => 6,'we' => 7, 'those' => 5, 'have' => 3} => {"the"=>6, "we"=>7, "those"=>5, "have"=>3} >> words.sort_by{ |x| x.last }.reverse => [["we", 7], ["the", 6], ["those", 5], ["have", 3]] 
 word_counts = { 'the' => 6, 'we' => 7, 'those' => 5, 'have' => 3, 'and' => 6 }; word_counts_sorted = word_counts.sort do |a,b| # sort on last field descending, then first field ascending if necessary b.last <=> a.last || a.first <=> b.first end puts "Unsorted\n" word_counts.each do |word,count| puts word + " " + count.to_s end puts "\n" puts "Sorted\n" word_counts_sorted.each do |word,count| puts word + " " + count.to_s end