原文:https://blog.blockscore.com/new-features-in-ruby-2-3/ discussion: http://stackoverflow.com/questions/34346653/how-do-i-use-arraydig-and-hashdig-introduced-in-ruby-2-3
Array#dig, Hash#dig, OpenStruct#dig in ruby 2.3, 抛弃老旧的 xx[:a][:b][:c],xx.fetch(:a, {}).fetch(:b, {}).fetch(:c, nil) 吧
results = [[[1, 2, 3]]]
results.dig(0, 0, 0) # => 1
results.dig(0, 1, 2) # => nil
user = {
user: {
address: {
street1: '123 Main street'
}
}
}
user.dig(:user, :address, :street1) # => '123 Main street'
user.dig(:user, :address, :street2) # => nil
address = OpenStruct.new('city' => "Anytown NC", 'zip' => 12345)
person = OpenStruct.new('name' => 'John Smith', 'address' => address)
person.dig(:address, 'zip') # => 12345
person.dig(:business_address, 'zip') # => nil
class Array
def dig(index, *indices)
Array[index, indices].flatten.inject(self) { |result, index| result.send(:[], index) rescue nil }
end unless Array.method_defined?(:dig)
end
class Hash
def dig(name, *names)
Array[name, names].flatten.inject(self) { |result, name| result.send(:[], name) rescue nil }
end unless Hash.method_defined?(:dig)
end
class OpenStruct
def dig(name, *names)
begin
name = name.to_sym
rescue NoMethodError
raise TypeError, "#{name} is not a symbol nor a string"
end
@table.dig(name, *names)
end unless OpenStruct.method_defined?(:dig)
end
也可以将 Array 和 Hash 合成一个,因为他们都 include Enumerable
module Enumerable
def dig(arg, *args)
Array[arg, args].flatten.inject(self) { |result, arg| result.send(:[], arg) rescue nil }
end unless Enumerable.method_defined?(:dig)
end