2010-03-29 30 views
127

Tôi có một băm truy cập mà tôi đang cố sắp xếp theo số lượng. Vấn đề tôi đang chạy vào 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ố.Làm thế nào để sắp xếp giá trị số băm của Ruby?

tức Hash Given:

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 được sắp xếp:

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

Mặc dù 745 là một con 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 là người đứng đầu, điều này khiến cuộc sống của tôi trở nên khó khăn. :)

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

Tôi đánh giá cao bất kỳ trợ giúp nào.

+0

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

Trả lời

225

Không có ý tưởng 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 chuỗi giá trị ... Bạn nên đảo ngược a1a2 trong 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 băm kết quả là, 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} 
+79

hoặc đơn giản là 'sort_by {| k, v | v} ' –

+1

thực sự ... Trả lời udpated :-) –

+0

Số của tôi đã trở lại dưới dạng 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 giảm dần .. cảm ơn phản hồi của bạn . –

8

Đó không phải là hành vi Tôi 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ể 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 không? Có thêm mã bạn không đăng không?

+0

Ahh bên phải của bạn có vẻ như kết quả trong mã của tôi đã trả về nó như là một chuỗi. Kiểu dữ liệu pesky. :) Đôi khi tôi chỉ là quá gần với vấn đề. Cảm ơn. –

+1

Yup. Thỉnh thoảng tôi nghe thấy ai đó nói đến Ruby là "không phân biệt". Ồ, không, nó chắc chắn đã được gõ. Nó không được đánh máy tĩnh. :) –

12

Đã được 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 } 

Được chuyển thành chuỗi dọc đường hay không, thao tác này sẽ thực hiện công việc.

70

Kể từ khi giá trị là mục cuối cùng, bạn có thể làm:

metrics.sort_by(&:last) 
+0

Câu trả lời tuyệt vời với sự đơn giản tuyệt vời! –

+4

Điều này thật tuyệt vời! bất kỳ referecne nào cho định nghĩa trước của '&: last'? –

+0

'sort_by (&: last)' là viết tắt hiệu quả cho 'sort_by {| x | x.last} 'https://stackoverflow.com/questions/1217088/what-does-mapname-mean-in-ruby –

Các vấn đề liên quan