単語がアルファベット順に表示された回数に基づいてドキュメントをソートしようとしています。Rubyでハッシュ値を最初にソートしてからキーを
Unsorted:
'the', '6'
'we', '7'
'those', '5'
'have', '3'
Sorted:
'we', '7'
'the', '6'
'those', '5'
'have', '3'
単語がアルファベット順に表示された回数に基づいてドキュメントをソートしようとしています。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"]
]
逆周波数でソートするように編集されています。
この投稿はかなり古いです。 IDは試してみた。 yを整数に変更していない場合、-Integer(y)の部分は何をしていますか? –
@ZachSmithこれは、数字を負にしているので、ソート順を最小から最小に最大から最小に逆順にします。 –
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
をあなたはおそらく値が整数ではなく、比較のために文字列になりたいです。
EDIT
おっと、それはあまりにもキーでソートする必要要件を見落とし。だから、:
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
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
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]]
を使用すると、ハッシュにsort
メソッドを使用すると、あなたの比較ブロックに2つの素子アレイを受け取りますあなたは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]]
ありがとうございます。私は 'Hash#sort'文書のためにhttp://ruby-doc.org/core/classes/Hash.html#M000743を見ていましたが、それらはかなり不十分です。良い方法があるはずだと分かっていた。 – Mikel
実際、[Enumerableモジュールのソート方法](http://ruby-doc.org/core/classes/Enumerable.html#M001480)をチェックしてください。これがHashのソート機能です。 – edgerunner
ええ、私はそれを考え出しました。私がすぐに気付かなかったのは、配列の配列を返すということでした。私は 'ハッシュ#each 'が効果的にペアを返すと思うので、そういうものを考えていたはずです。 – Mikel
これを試してみて、配列の配列であることを
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 1.9を前提としています。 Ruby 1.8では、ハッシュは順序付けされていないので、ソートされた結果をハッシュに変換することはできません。順序情報を失うため、配列として保持する必要があります。
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
# }
注:これはあなたが番号を使用することを前提としていた結果がハッシュはルビーに固有の順序を持っていないので、
ソートされていないリストに何かを追加して、アルファベット順にソートしているかどうかを確認することをお勧めします。私は 'と=> 6 'を追加しました。つまり、'、 '6の前に'と '6'があるはずです。 – Mikel
あなたの問題をもっときれいに解決するために私の答えを更新しました:)。見てみな。 –