2016-03-10 17 views
18

Trong Rails, bạn có thể làm hash.try(:[], :key) giúp nếu hash có khả năng là nil. Có phiên bản tương đương để sử dụng toán tử điều hướng an toàn Ruby 2.3 mới &. với [] không?Điều hướng an toàn tương đương với Rails thử băm

+0

có thể trùng lặp của [Ruby - Truy cập băm đa chiều và tránh truy cập đối tượng nil] (https://stackoverflow.com/question/10130726/ruby-access-multidimensional-băm-và-tránh-truy-nil-đối tượng) – kolen

Trả lời

22

&. không tương đương với Rails' try, nhưng bạn có thể sử dụng &. cho băm. Chỉ cần sử dụng nó, không có gì đặc biệt.

hash[:key1]&.[](:key2)&.[](:key3) 

Mặc dù tôi không làm điều đó.

+2

Điểm tốt với '& .' và' try' là khác nhau. Tôi chỉ nghĩ đến trường hợp 'băm' là' nil'. Những gì tôi đã kết thúc bằng cách sử dụng là 'băm &. [] (: Khóa)' –

+0

Điều này chỉ hoạt động với ruby ​​2.3+? – bbozo

+0

@bbozo Có. '& .' được giới thiệu trong Ruby 2.3. – sawa

2

Được chấp nhận câu trả lời sẽ không chiếm khi hash là con số không ...

Bạn có thể viết lại những gì bạn đã sử dụng toán tử nav an toàn trước khi .try và điều đó sẽ làm việc

hash&.try(:[], :key)

nhưng bạn cũng có thể sử dụng:

http://ruby-doc.org/core-2.3.0_preview1/Hash.html#method-i-dig

A w ay bạn có thể làm điều này trên một băm bằng cách thực hiện ...

hash&.dig(:key1, :key2 ...) 

sẽ trả về 0 nếu không tìm thấy khóa nào.

{ key1: { key2: 'info' } } 

sẽ trở lại 'thông tin'

{ key1: { wrong_key: 'info' } } 

sẽ trở nil

20

Pre của Ruby 2.3

tôi thường có cái gì đó như đặt này vào intializer tôi:

Class Hash 
    def deep_fetch *args 
     x = self 
     args.each do |arg| 
     x = x[arg] 
     return nil if x.nil? 
     end 
     x 
    end 
end 

và sau đó

response.deep_fetch 'PaReqCreationResponse', 'ThreeDSecureVERes', 'Message', 'VERes', 'CH', 'enrolled' 

trong một trường hợp lập dị.

Sự đồng thuận chung trong cộng đồng có vẻ là để tránh cả hai cố gắng và các nhà điều hành cô đơn &.

của Ruby 2.3 và sau

Hash#dig phương pháp bây giờ mà chỉ làm điều đó:

lấy đối tượng giá trị tương ứng với từng đối tượng khóa liên tục.

h = { foo: {bar: {baz: 1}}} 

h.dig(:foo, :bar, :baz)   #=> 1 
h.dig(:foo, :zot)     #=> nil 

http://ruby-doc.org/core-2.3.0_preview1/Hash.html#method-i-dig

+1

Có vẻ tương tự đáng ngờ trong trường hợp sử dụng để 'dig', được giới thiệu trong 2.3 giống như' & .'. Có sự khác biệt nào không? –

+0

Thật vậy, cảm ơn bạn! :) – bbozo

+4

IMHO này phải là câu trả lời được chấp nhận. –

1

Trong khi hash&.[](:key) là thanh lịch đến rubyist đào tạo, tôi chỉ cần sử dụng hash && hash[:key] như nó đọc tốt hơn và trực quan hơn cho các lập trình viên đến sau tôi, những người có thể không được như quen thuộc với sự phức tạp của ruby. Một số nhân vật phụ trong codebase đôi khi có thể tiết kiệm rất nhiều googling cho người khác.

(Căn cứ vào bối cảnh mà bạn muốn sử dụng trong này là trong một tuyên bố có điều kiện, tất nhiên.)

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