Bagaimana cara mengurutkan Ruby Hash berdasarkan nilai angka?


154

Saya memiliki hash balasan yang ingin saya urutkan berdasarkan hitungan. Masalah yang saya temui adalah bahwa fungsi Hash.sort default mengurutkan angka seperti string daripada berdasarkan ukuran angka.

yaitu Given Hash:

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

Menjalankan kode ini:

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

akan mengembalikan array yang diurutkan:

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

Meskipun 745 adalah jumlah yang lebih besar dari 9, 9 akan muncul pertama dalam daftar. Ketika mencoba untuk menunjukkan siapa yang memiliki hitungan teratas, ini membuat hidup saya sulit. :)

Ada ide tentang cara mengurutkan hash (atau bahkan array) dengan ukuran nilai angka?

Saya menghargai bantuan apa pun.


versi ruby ​​apa yang kamu gunakan? hasil
sortirmu

Jawaban:


268

Tidak tahu bagaimana Anda mendapatkan hasil Anda, karena itu tidak akan mengurutkan berdasarkan nilai string ... Anda harus membalikkan a1dan a2dalam contoh Anda

Cara terbaik dalam hal apa pun (sesuai Mladen) adalah:

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]]

Jika Anda membutuhkan hash, Anda dapat menggunakan to_h(dalam Ruby 2.0+)

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

84
atau hanyasort_by{|k,v| v}
Mladen Jablanović

Nomor saya kembali sebagai string, yang memperbaikinya .. Saya memiliki a2 dan a1 dalam urutan itu karena saya ingin hasilnya mengurutkan decending .. terima kasih atas tanggapan Anda.
Dustin M.

ini sebabnya saya suka Ruby ... masalah seperti itu adalah rasa sakit di kepala dalam bahasa lain. sangat sederhana
Hady Elsahar

18
@Elchin: Anda bisa menggunakanmetrics.sort_by{ |k, v| v }.reverse.to_h
Marc-André Lafortune

4
Sebenarnya lebih sederhana seperti: hash.sort_by (&: last) dengan peringatan yang sama tentang mendapatkan array berpasangan vs. Hash.
Gerry Gleason


14

Sudah dijawab tetapi masih. Ubah kode Anda menjadi:

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

Dikonversi menjadi string di sepanjang jalan atau tidak, ini akan melakukan pekerjaan.


9

Itu bukan perilaku yang saya lihat:

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]]

Apakah mungkin bahwa di suatu tempat di sepanjang garis angka Anda sedang dikonversi ke string? Apakah ada lebih banyak kode yang tidak Anda posting?


Ahh benar sepertinya hasil kode saya mengembalikannya sebagai string. Jenis data sial. :) Terkadang saya terlalu dekat dengan masalah. Terima kasih.
Dustin M.

1
Ya. Terkadang saya mendengar seseorang menyebut Ruby sebagai "tidak diketik". Oh, tidak, sudah pasti diketik. Hanya saja tidak diketik secara statis. :)
Jacob Mattison
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.