2009-06-11 30 views

Trả lời

11

Trong Ruby 1.9, Hash es được sắp xếp, nhưng Hash#sort vẫn trả lại một Array trong số Array s. Tưởng tượng rằng! Nó ngụ ý rằng bạn có thể xây dựng phương pháp phân loại của riêng bạn trên đầu trang của nó.

class Hash 
    def sorted_hash(&block) 
    self.class[sort(&block)] # Hash[ [[key1, value1], [key2, value2]] ] 
    end 
end 

Hash es không được phân loại trong Ruby 1.8. Nếu bạn muốn tương thích với Ruby 1.8, bạn có thể sử dụng OrderedHash của ActiveSupport. Nó hoạt động như một 1.9- Hash, vì vậy bạn có thể xác định cùng một phương pháp sorted_hash vào nó:

class ActiveSupport::OrderedHash 
    def sorted_hash(&block) 
    self.class[sort(&block)] 
    end 
end 

hash = ActiveSupport::OrderedHash.new 
hash["b"] = "b" 
hash["a"] = "a" 
hash    #=> {"b"=>"b", "a"=>"a"} => unsorted 
hash.sorted_hash #=> {"a"=>"a", "b"=>"b"} => sorted! 

Bạn cần phải sao chép các phương pháp sorted_hash mã của bạn, bởi vì nó không tồn tại theo mặc định!

Cập nhật cho phân loại sâu: Nếu bạn đang tìm kiếm để sắp xếp trên một cái gì đó khác hơn là phím băm, vượt qua một khối với phương pháp sorted_hash như sau (giả sử việc thực hiện từ trên cao):

hash = ActiveSupport::OrderedHash.new 
hash["a"] = { "attr" => "2", "..." => "..." } 
hash["b"] = { "attr" => "1", "..." => "..." } 

# Unsorted. 
hash 
    #=> {"a"=>{"attr"=>"2", "..."=>"..."}, "b"=>{"attr"=>"1", "..."=>"..."}} 

# Sort on the "attr" key. (Assuming every value is a Hash itself!) 
hash.sorted_hash { |a, b| a[1]["attr"] <=> b[1]["attr"] } 
    #=> {"b"=>{"attr"=>"1", "..."=>"..."}, "a"=>{"attr"=>"2", "..."=>"..."}} 
+0

Tôi không nhận được bạn. Tôi nhìn vào mã nguồn OrderedHash của đường ray 2.3.2 và tôi không thấy bất cứ điều gì liên quan đến phương pháp phân loại. – Dharam

+0

@satynos: Tôi đã làm rõ nó một chút, hy vọng. Bạn cần phải tự định nghĩa sắp xếp_hash, nhưng nó thực sự dễ dàng! Chỉ cần sao chép thực hiện của tôi nếu bạn muốn. – molf

+0

@molf: xuất sắc ... cảm ơn vì phản hồi và trợ giúp thực hiện. Ngoài ra nếu tôi thực hiện phương pháp của bạn trong lớp Hash, nó sẽ làm việc? hoặc nó phải được thực hiện trong ActiveSupport :: OrderedHash? – Dharam

8

Phát ban là cấu trúc dữ liệu không được phân loại cơ bản; Hash#sort là, thực sự, những gì bạn muốn. Hoặc là, hoặc sắp xếp danh sách các khóa và sau đó sử dụng danh sách đó để liệt kê khi đã đến lúc xuất kết quả băm, thay vì liệt kê trực tiếp trên băm bằng các phương thức riêng của nó.

+3

Về mặt kỹ thuật, Hashes được đặt hàng trong Ruby 1.9. Nhưng tôi nghĩ rằng nó vẫn còn tốt hơn để đối xử với họ như thể họ không, vì hỗ trợ cho sắp xếp lại và như vậy không tồn tại. – Chuck

+0

Jim, bạn có thể cho tôi một ví dụ không? – Dharam

+0

"Về mặt kỹ thuật, Hashes được đặt hàng trong Ruby 1.9" ... điều này khiến tôi rất buồn. Một băm không có nghĩa vụ phải có bất kỳ thứ tự ngầm định nào! Chắc chắn, tôi hiểu muốn đặt hàng đôi khi ... nhưng tạo một tên khác cho cấu trúc dữ liệu đó! Grr. – Beska

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