2008-10-04 29 views
34

Tạo băm băm trong Ruby cho phép thuận tiện tìm kiếm hai chiều (hoặc nhiều hơn). Tuy nhiên, khi chèn một phải luôn kiểm tra xem chỉ mục đầu tiên đã tồn tại trong băm hay chưa. Ví dụ:Hashes of Hashes Idiom trong Ruby?

h = Hash.new 
h['x'] = Hash.new if not h.key?('x') 
h['x']['y'] = value_to_insert 

Nó sẽ là thích hợp hơn để làm như sau nơi Hash mới được tạo ra tự động:

h = Hash.new 
h['x']['y'] = value_to_insert 

Tương tự như vậy, khi nhìn lên một giá trị mà chỉ số đầu tiên không tồn tại, nó sẽ là thích hợp hơn nếu nil được trả về thay vì nhận được một phương pháp không xác định cho lỗi '[]'.

looked_up_value = h['w']['z'] 

Có thể tạo một lớp trình bao Hash có hành vi này, nhưng có một thành ngữ Ruby hiện có để hoàn thành tác vụ này không?

+0

Có băm của thành ngữ băm mà muốn trả về 0 sau một độ sâu nhất định? (Tôi đếm những thứ và tôi đang sử dụng h [: foo] [: bar] [: baz] + = 1) –

Trả lời

54

Bạn có thể vượt qua Hash.new chức năng một khối được thực hiện để mang lại một giá trị mặc định trong trường hợp giá trị truy vấn không tồn tại được nêu ra:

h = Hash.new { |h, k| h[k] = Hash.new } 

Tất nhiên, điều này có thể được thực hiện một cách đệ quy.

/CHỈNH SỬA: Ồ, có an article trả lời câu hỏi này.

Vì lợi ích của sự hoàn chỉnh, đây là giải pháp từ các bài báo cho băm sâu tùy ý:

hash = Hash.new(&(p=lambda{|h,k| h[k] = Hash.new(&p)})) 

Tín đi đến Kent từ Data Noise.

+1

Wow. Ấn tượng đấy. –

+0

Liên kết chết. Mặc dù giải pháp ấn tượng. –

+1

Liên kết chết được chuyển đến đây http://inquirylabs.com/blog2009/2006/09/20/ruby-hashes-of-arbitrary-depth/ – Autodidact

4

Tự động hóa, được gọi là, vừa là lời chúc vừa là lời nguyền. Những rắc rối có thể là nếu bạn "nhìn" ở một giá trị trước khi nó được xác định, bạn đang mắc kẹt với hash này trống trong khe và bạn sẽ cần phải cắt nó đi sau này.

Nếu bạn không nhớ một chút tình trạng hỗn loạn, bạn có thể luôn luôn chỉ mứt hoặc bằng với tờ khai phong cách mà sẽ cho phép bạn xây dựng cấu trúc dự kiến ​​như bạn truy vấn nó:

((h ||= { })['w'] ||= { })['z'] 
Các vấn đề liên quan