Làm cách nào để sắp xếp Ruby Hash theo giá trị số?


154

Tôi có một hàm băm mà tôi đang cố gắng sắp xếp theo số lượng. Vấn đề tôi gặp phải là hàm Hash.sort mặc định sắp xếp các số như chuỗi thay vì theo kích thước số.

tức là đã cho Hash:

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

Chạy mã này:

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

sẽ trả về một mảng đã sắp xếp:

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

Mặc dù 745 là một số lớn hơn 9, 9 sẽ xuất hiện đầu tiên trong danh sách. Khi cố gắng thể hiện ai có số lượng cao nhất, điều này đang khiến cuộc sống của tôi trở nên khó khăn. :)

Bất kỳ ý tưởng về cách sắp xếp một hàm băm (hoặc một mảng chẵn) theo kích thước giá trị số?

Tôi đánh giá cao bất kỳ sự giúp đỡ.


bạn sử dụng phiên bản ruby ​​nào? kết quả sắp xếp của bạn rất kỳ lạ
fl00r

Câu trả lời:


268

Không biết làm thế nào bạn có kết quả của bạn, vì nó sẽ không sắp xếp theo giá trị chuỗi ... Bạn nên đảo ngược a1a2trong ví dụ của bạn

Cách tốt nhất trong mọi trường hợp (theo Mladen) là:

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

Nếu bạn cần một hàm băm, bạn có thể sử dụng to_h(trong Ruby 2.0+)

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

84
hoặc đơn giảnsort_by{|k,v| v}
Mladen Jablanović

Số của tôi đã trở lại dưới dạng một chuỗi, đã sửa nó .. Tôi đã có a2 và a1 theo thứ tự đó vì tôi muốn kết quả sắp xếp quyết định .. mặc dù cảm ơn phản hồi của bạn.
Dustin M.

đây là lý do tại sao tôi yêu Ruby ... vấn đề như vậy là đau đầu trong các ngôn ngữ khác. thật đơn giản
Hady Elsahar

18
@Elchin: bạn có thể sử dụngmetrics.sort_by{ |k, v| v }.reverse.to_h
Marc-André Lafortune

4
Trên thực tế thậm chí còn đơn giản hơn như: hash.sort_by (&: last) với cùng một cảnh báo về việc lấy một mảng các cặp so với Hash.
Gerry Gl lý


14

Đã trả lời nhưng vẫn còn. Thay đổi mã của bạn thành:

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

Chuyển đổi thành chuỗi trên đường đi hoặc không, điều này sẽ thực hiện công việc.


9

Đó không phải là hành vi tôi đang thấy:

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

Có thể là một nơi nào đó dọc theo dòng số của bạn đang được chuyển đổi thành chuỗi? Có nhiều mã bạn không đăng?


Ahh quyền của bạn có vẻ như kết quả trong mã của tôi đã trả lại nó dưới dạng một chuỗi. Các loại dữ liệu khó chịu. :) Đôi khi tôi chỉ quá gần với vấn đề. Cảm ơn.
Dustin M.

1
Vâng Thỉnh thoảng tôi nghe thấy ai đó gọi Ruby là "cởi trói". Ồ, không, nó chắc chắn được gõ. Nó chỉ không được gõ tĩnh. :)
Jacob Mattison
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.