我正在尝试编写一个接受未知数量参数的方法,并对它们执行Hash #dig。
def unknown_dig(hash, *args)
# do some magic?
hash.dig(non_array_args)
end
#example usage
unknown_dig(hash, 'a', 'b', 'c')
这可能吗?
答案 0 :(得分:4)
Hash#dig在Ruby v2.3中被赋予了我们。要支持早期的Ruby版本,您可以使用Enumerable#reduce(又名inject
)。这就是我小时候这样做的原因。
def dig_it(h,*keys)
keys.reduce(h) { |obj,k| obj && obj[k] }
end
h = { a: { b: 1 } }
dig_it(h, :a, :b)
#=> 1
dig_it(h, :a)
#=> {:b=>1}
dig_it(h, :a, :c)
#=> nil
dig_it(h, :c, :b)
#=> nil
如果obj
是哈希,就像它最初(h
)一样,当k
传递给块obj[k] #=> nil
时,如果obj
没有密钥k
(如果obj
有一个密钥k
,其值为nil
),在这种情况下obj && obj[k] #=> obj && nil #=> nil
。因此,对于传递给块的obj && obj[k] #=> nil && obj[k] #=> nil
的每个剩余元素,块计算将为keys
。 (nil[k]
会引发异常,但永远不会执行。)如果散列obj
的键k
的值为false
,则除了{{1
false
)
答案 1 :(得分:2)
Hash #dig(在Ruby 2.3中定义)已经这样做了:
hash = { a: { b: 1 } }
hash.dig(:a, :b) == hash.dig(*[:a, :b])
如果你想要更多功能样式(将散列作为参数传递,而不是在其上调用方法),这很简单:
def hash_dig(hash, *args)
hash.dig(*args)
end