2011-01-25 43 views
1

我试图根据单词出现的次数对文档进行排序,然后按字母顺序排列,因此输出时它看起来像这样。在Ruby中按照其值排序首先键入

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

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

我建议在未排序列表中添加一些内容,以帮助明确按字母顺序对单词进行排序是否正常。我加了`and => 6`,这意味着我们应该在`6,`之前看到`和6'。 – Mikel 2011-01-25 07:21:06

+0

我已经更新了我的答案,以更清晰地解决您的问题:)。一探究竟。 – 2011-01-25 07:43:57

回答

10

试试这个:

假设:

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

编辑按逆向频率排序。

+0

这篇文章比较陈旧。但思想编号尝试。如果不将y改为整数,那么-Integer(y)部分在做什么? – 2014-03-23 09:50:20

+1

@ ZachSmith它使数字为负数,实际上将排序顺序从最小到最大从最大到最小反转。 – 2016-01-25 08:11:39

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 
0
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 
0

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

当您使用哈希的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]] 

注意,结果是一个数组的数组,因为散列不具有红宝石内在为了

1

试试这个:

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]] 
1
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中,哈希不是有序的,所以你不能将排序后的结果转换回散列,因为这会丢失排序信息,你必须将它保存为一个数组。