Apakah ini cara terbaik untuk mengurutkan hash dan mengembalikan objek Hash (bukan Array):
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}
Apakah ini cara terbaik untuk mengurutkan hash dan mengembalikan objek Hash (bukan Array):
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}
Jawaban:
Di Ruby 2.1 itu sederhana:
h.sort.to_h
h.sort{|a,z|a<=>z}.to_h
(diuji 2.1.10, 2.3.3)
a
array, bukan hanya kuncinya). Saya sudah menghapus komentar saya.
h.map(&:sort).map(&:to_h)
.
Catatan: Ruby> = 1.9.2 memiliki hash yang mempertahankan pesanan: kunci pesanan yang dimasukkan akan menjadi urutan yang disebutkan. Di bawah ini berlaku untuk versi yang lebih lama atau kode yang kompatibel dengan mundur.
Tidak ada konsep hash yang diurutkan. Jadi tidak, apa yang Anda lakukan tidak benar.
Jika Anda ingin diurutkan untuk ditampilkan, kembalikan string:
"{" + h.sort.map{|k,v| "#{k.inspect}=>#{v.inspect}"}.join(", ") + "}"
atau, jika Anda menginginkan kunci secara berurutan:
h.keys.sort
atau, jika Anda ingin mengakses elemen secara berurutan:
h.sort.map do |key,value|
# keys will arrive in order to this block, with their associated value.
end
tetapi secara ringkas, tidak masuk akal untuk berbicara tentang hash yang diurutkan. Dari dokumen , "Urutan di mana Anda melintasi hash dengan salah satu kunci atau nilai mungkin tampak sewenang-wenang, dan umumnya tidak akan berada dalam urutan penyisipan." Jadi memasukkan kunci dalam urutan tertentu ke dalam hash tidak akan membantu.
Saya selalu menggunakan sort_by
. Anda perlu membungkus #sort_by
output dengan Hash[]
untuk membuatnya menghasilkan hash, jika tidak output array array. Atau, untuk mencapai ini, Anda dapat menjalankan #to_h
metode pada array tuple untuk mengubahnya menjadi k=>v
struktur (hash).
hsh ={"a" => 1000, "b" => 10, "c" => 200000}
Hash[hsh.sort_by{|k,v| v}] #or hsh.sort_by{|k,v| v}.to_h
Ada pertanyaan serupa di " Bagaimana cara mengurutkan Ruby Hash berdasarkan nilai angka? ".
sort_by
hash akan mengembalikan array. Anda perlu memetakannya sebagai hash lagi. Hash[hsh.sort_by{|k,v| v}]
hsh.sort_by(&:last).to_h => {"b"=>10, "a"=>1000, "c"=>200000}
.
to_h
hanya didukung di Ruby 2.1.0+
sort_by{|k,v| v}.to_h)
Tidak, bukan (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)
Untuk perbedaan hash besar akan tumbuh hingga 10x dan lebih banyak
Anda memberikan jawaban terbaik untuk diri sendiri di OP: Hash[h.sort]
Jika Anda menginginkan lebih banyak kemungkinan, berikut adalah modifikasi hash asli untuk membuatnya disortir:
h.keys.sort.each { |k| h[k] = h.delete k }
Sortir hash dengan kunci , kembalikan hash di Ruby
Dengan penghancuran dan semacam Hash
hash.sort { |(ak, _), (bk, _)| ak <=> bk }.to_h
Dihitung # sort_by
hash.sort_by { |k, v| k }.to_h
Hash # urutkan dengan perilaku default
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 }
Catatan: <Ruby 2.1
array = [["key", "value"]]
hash = Hash[array]
hash #=> {"key"=>"value"}
Catatan:> Ruby 2.1
[["key", "value"]].to_h #=> {"key"=>"value"}
v
Anda harus hash.sort_by { |k, _v| k }.to_h
ActiveSupport :: OrderedHash adalah opsi lain jika Anda tidak ingin menggunakan ruby 1.9.2 atau memutar solusi Anda sendiri.
@ordered = {}
@unordered.keys.sort.each do |key|
@ordered[key] = @unordered[key]
end
Saya memiliki masalah yang sama (saya harus menyortir peralatan saya dengan nama mereka) dan saya menyelesaikannya seperti ini:
<% @equipments.sort.each do |name, quantity| %>
...
<% end %>
@ peralatan adalah hash yang saya bangun di model saya dan kembali pada controller saya. Jika Anda memanggil .sort maka akan mengurutkan hash berdasarkan nilai kuncinya.
Saya menyukai solusinya di posting sebelumnya.
Saya membuat kelas mini, menyebutnya class AlphabeticalHash
. Ini juga memiliki metode yang disebut ap
, yang menerima satu argumen, sebuah Hash
, sebagai masukan: ap variable
. Akin to pp ( pp variable
)
Tetapi ia akan (mencoba dan) mencetak dalam daftar abjad (kuncinya). Entah apakah ada orang lain yang ingin menggunakan ini, tersedia sebagai permata, Anda dapat menginstalnya seperti:gem install alphabetical_hash
Bagi saya, ini cukup sederhana. Jika orang lain membutuhkan lebih banyak fungsi, beri tahu saya, saya akan memasukkannya ke dalam permata.
EDIT: Kredit untuk Peter , yang memberi saya ide. :)
each
ataueach_pair
mengulanginya. Bahkan kemudian, saya mungkin masih mengambil kunci, mengurutkannya, lalu beralih ke mereka mengambil nilai-nilai yang diperlukan. Itu memastikan kode akan berperilaku benar pada Rubi yang lebih lama.