2010-12-13 13 views
3

値に基づいてルビでハッシュをソートしてからキーをソートしますか?例えば値に基づいてルビのハッシュをソートしてからキー

h = {4 => 5, 2 => 5, 7 => 1} 

は私が

h.sort {|x,y| x[1] <=> y[1]} 

を実行して値に基づいて分類することができますが、私はその値に基づいてソートする方法を見つけ出すことができず、

[[7, 1], [2,5], [4, 5]] 

に並べ替えます値が同じ場合はキー

答えて

12
h.sort_by {|k, v| [v, k] } 

これは、ArrayComparableに混在し、要素ごとに<=>を定義しているという事実を利用しています。以上の読み取り可能であってもなくてもよい

h.sort_by(&:reverse) 

に相当する上記の

h.sort_by {|el| el.reverse } 

に相当する

注意。

の場合は、通常Hashが最初にキーでソートされ、次に値によってソートされます。たぶん小さなコメント付き:

h.sort_by(&:reverse) # sort by value first, then by key 

注:あなたは、単にいくつかのプロパティの<=>方法、(キーではなく、一般的な比較機能により、すなわちソート)に委譲したい場合は、一般的sort_byを使用することが好まれますsortの代わりに読むのがはるかに簡単です。一般的に、それはまた速くなることもありますが、読みやすさの観点が重要です。

実際にが必要な場合は、独自の比較関数を作成してください。

だから、あなたの非稼働の例では、より良い個人的に

h.sort_by {|el| el[1] } 

ように書かれるだろう、私が代わりにel[0]el[1]を使用するのでは、ブロックのパラメータリストに非構造バインドを使用することを好む:

h.sort_by {|key, value| value } 

しかし、この特定のケースでは、もel.lastと同じであるため、単に

と書くことができます
h.sort_by(&:last) 
+0

+1絶対に必要でない場合に比較関数を定義するのではなく、「キー付き」ソートを使用する場合。 –

+0

@Karl Knechtel:ありがとう! 「キー」は私が探している言葉でした。 –

+0

ところで、 '{| k、v | ...'は毎回** 1 **引数を実際に受け取っていることを知り、それを2タプルとして解凍する必要がありますか?それは何とか 'h.sort_by'コンテキストから推測されますか? (あなたがそこに持っている用語を使用するには、「構造化バインド」を実行するかどうかをどのように知っていますか?)私は、このレベルでlambdaのRuby実装がどのように機能するのかを実際には理解していません。 –

関連する問題