Ruby Hashを数値でソートする方法は?


154

カウントでソートしようとしているカウンターハッシュがあります。私が遭遇している問題は、デフォルトのHash.sort関数が数値サイズではなく文字列のような数値をソートすることです。

すなわち、与えられたハッシュ:

metrics = {"sitea.com" => 745, "siteb.com" => 9, "sitec.com" => 10 }

このコードを実行する:

metrics.sort {|a1,a2| a2[1]<=>a1[1]}

ソートされた配列を返します:

[ 'siteb.com', 9, 'sitea.com', 745, 'sitec.com', 10]

745は9よりも大きい数値ですが、9がリストの最初に表示されます。誰がトップカウントかを見せようとするとき、これは私の人生を難しくしています。:)

数値のサイズでハッシュ(または配列さえ)をソートする方法についてのアイデアはありますか?

どんな助けにも感謝します。


どのルビーバージョンを使用していますか?並べ替えの結果が非常に奇妙です
fl00r 2010年

回答:


268

文字列値で並べ替えられないため、どのように結果が得られたかはわかりません...逆a1a2して、例では

どんな場合でも(Mladenによる)最良の方法は次のとおりです。

metrics = {"sitea.com" => 745, "siteb.com" => 9, "sitec.com" => 10 }
metrics.sort_by {|_key, value| value}
  # ==> [["siteb.com", 9], ["sitec.com", 10], ["sitea.com", 745]]

結果としてハッシュが必要な場合は、to_h(Ruby 2.0以降)を使用できます

metrics.sort_by {|_key, value| value}.to_h
  # ==> {"siteb.com" => 9, "sitec.com" => 10, "sitea.com", 745}

84
または単にsort_by{|k,v| v}
MladenJablanović2010年

私の番号は文字列として返され、それを修正しました..結果を降順で並べ替えたいので、a2とa1の順序でした。フィードバックをありがとうございます。
ダスティン

これが私がRubyを愛する理由です...そのような問題は他の言語では頭が痛いです。とてもシンプル
Hady Elsahar、

18
@Elchin:あなたは使用することができますmetrics.sort_by{ |k, v| v }.reverse.to_h
マルク=アンドレ・Lafortune

4
実際にはさらに単純です:hash.sort_by(&:last)で、ペアの配列とハッシュの配列を取得する場合と同じ注意点があります。
Gerry Gleason、


14

すでに回答しましたが、まだです。コードを次のように変更します。

metrics.sort {|a1,a2| a2[1].to_i <=> a1[1].to_i }

途中で文字列に変換されるかどうかは、これで十分です。


9

それは私が見ている行動ではありません:

irb(main):001:0> metrics = {"sitea.com" => 745, "siteb.com" => 9, "sitec.com" =>
 10 }
=> {"siteb.com"=>9, "sitec.com"=>10, "sitea.com"=>745}
irb(main):002:0> metrics.sort {|a1,a2| a2[1]<=>a1[1]}
=> [["sitea.com", 745], ["sitec.com", 10], ["siteb.com", 9]]

行のどこかで数値が文字列に変換されている可能性はありますか?投稿していないコードが他にありますか?


私のコードの結果は文字列として返されていたようです。厄介なデータ型。:)時々私は問題に近すぎます。ありがとう。
ダスティン

1
うん。時々、誰かがRubyを「型なし」と呼ぶのを聞く。ああ、いや、それは間違いなく型付けされています。静的に型付けされていないだけです。:)
ジェイコブ・マティソン、
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.