これはハッシュを並べ替えて、(配列の代わりに)Hashオブジェクトを返す最良の方法でしょうか?
h = {"a"=>1, "c"=>3, "b"=>2, "d"=>4}
# => {"a"=>1, "c"=>3, "b"=>2, "d"=>4}
Hash[h.sort]
# => {"a"=>1, "b"=>2, "c"=>3, "d"=>4}
これはハッシュを並べ替えて、(配列の代わりに)Hashオブジェクトを返す最良の方法でしょうか?
h = {"a"=>1, "c"=>3, "b"=>2, "d"=>4}
# => {"a"=>1, "c"=>3, "b"=>2, "d"=>4}
Hash[h.sort]
# => {"a"=>1, "b"=>2, "c"=>3, "d"=>4}
回答:
Ruby 2.1では簡単です。
h.sort.to_h
h.sort{|a,z|a<=>z}.to_h
(2.1.10、2.3.3でテスト済み)
a
単なるキーではなく配列です)。コメントを削除しました。
h.map(&:sort).map(&:to_h)
。
注:Ruby> = 1.9.2には順序を維持するハッシュがあります。キーが挿入される順序は、列挙される順序になります。以下は、古いバージョンまたは下位互換性のあるコードに適用されます。
ソートされたハッシュの概念はありません。いいえ、あなたがやっていることは正しくありません。
表示用に並べ替えたい場合は、文字列を返します。
"{" + h.sort.map{|k,v| "#{k.inspect}=>#{v.inspect}"}.join(", ") + "}"
または、キーを順番に並べたい場合:
h.keys.sort
または、要素に順番にアクセスしたい場合:
h.sort.map do |key,value|
# keys will arrive in order to this block, with their associated value.
end
しかし、要約すると、ソートされたハッシュについて話しても意味がありません。docsから、「キーまたは値のどちらかでハッシュをトラバースする順序は任意に見える可能性があり、通常は挿入順序にはなりません。」そのため、ハッシュに特定の順序でキーを挿入しても効果がありません。
私はいつも使ってきましたsort_by
。ハッシュを#sort_by
出力するHash[]
には、出力をラップする必要があります。そうしないと、配列の配列が出力されます。あるいは、これを達成#to_h
するために、タプルの配列に対してメソッドを実行して、それらをk=>v
構造(ハッシュ)に変換することができます。
hsh ={"a" => 1000, "b" => 10, "c" => 200000}
Hash[hsh.sort_by{|k,v| v}] #or hsh.sort_by{|k,v| v}.to_h
「Rubyハッシュを数値でソートする方法」にも同様の質問があります。
sort_by
ハッシュで使用すると、配列が返されます。もう一度ハッシュとしてマップする必要があります。Hash[hsh.sort_by{|k,v| v}]
hsh.sort_by(&:last).to_h => {"b"=>10, "a"=>1000, "c"=>200000}
。
to_h
はRuby 2.1.0以降でのみサポートされていることに注意してください
sort_by{|k,v| v}.to_h)
いいえ、そうではありません(Ruby 1.9.x)
require 'benchmark'
h = {"a"=>1, "c"=>3, "b"=>2, "d"=>4}
many = 100_000
Benchmark.bm do |b|
GC.start
b.report("hash sort") do
many.times do
Hash[h.sort]
end
end
GC.start
b.report("keys sort") do
many.times do
nh = {}
h.keys.sort.each do |k|
nh[k] = h[k]
end
end
end
end
user system total real
hash sort 0.400000 0.000000 0.400000 ( 0.405588)
keys sort 0.250000 0.010000 0.260000 ( 0.260303)
大きなハッシュの場合、差は最大10倍以上になります
あなたはOPで自分に最良の答えを出しました:Hash[h.sort]
より多くの可能性を求めている場合は、元のハッシュをその場で変更してソートします。
h.keys.sort.each { |k| h[k] = h.delete k }
キーでハッシュをソートし、Rubyでハッシュを返す
非構造およびハッシュ#ソート
hash.sort { |(ak, _), (bk, _)| ak <=> bk }.to_h
列挙型#sort_by
hash.sort_by { |k, v| k }.to_h
デフォルトの動作のHash#sort
h = { "b" => 2, "c" => 1, "a" => 3 }
h.sort # e.g. ["a", 20] <=> ["b", 30]
hash.sort.to_h #=> { "a" => 3, "b" => 2, "c" => 1 }
注:<Ruby 2.1
array = [["key", "value"]]
hash = Hash[array]
hash #=> {"key"=>"value"}
注:> Ruby 2.1
[["key", "value"]].to_h #=> {"key"=>"value"}
v
、アンダースコアを前に付ける必要がありますhash.sort_by { |k, _v| k }.to_h
ActiveSupport :: OrderedHashは、Ruby 1.9.2を使用したくない場合や、独自の回避策を導入したくない場合の別のオプションです。
@ordered = {}
@unordered.keys.sort.each do |key|
@ordered[key] = @unordered[key]
end
私は同じ問題を抱えていました(私は自分の機器を名前で並べ替えなければなりませんでした)、私はこのように解決しました:
<% @equipments.sort.each do |name, quantity| %>
...
<% end %>
@equipmentsは、モデルに基づいて構築し、コントローラーに返すハッシュです。.sortを呼び出すと、キーの値に基づいてハッシュがソートされます。
以前の投稿の解決策が気に入りました。
私はそれと呼ばれるミニクラスを作りましたclass AlphabeticalHash
。またap
、1つの引数a Hash
を入力として受け入れると呼ばれるメソッドもありますap variable
。似ているpp(pp variable
)
しかし、それは(試行して)アルファベット順のリスト(そのキー)で印刷します。Dunno他の誰かがこれを使用したい場合は、gemとして入手できます。次のようにインストールできます。gem install alphabetical_hash
私にとって、これは十分に簡単です。他の人がより多くの機能を必要とするなら、知らせてください、私はそれを宝石に含めます。
編集:クレジットは、私にアイデアを与えたピーターに送られます。:)
each
たりeach_pair
、反復したりしない限り、ハッシュをソートすることには多くの利点があるとは思いません。それでも、おそらくキーを取得し、それらを並べ替えて、必要に応じてそれらを繰り返して値を取得します。これにより、古いルビーでコードが正しく動作するようになります。