[英]Ruby hash equivalent to Python dict setdefault
在Python中,可以读取字典/散列键,同时将键设置为默认值(如果尚不存在)。
例如:
>>> d={'key': 'value'}
>>> d.setdefault('key', 'default')
'value' # returns the existing value
>>> d.setdefault('key-doesnt-exist', 'default')
'default' # sets and returns default value
>>> d
{'key-doesnt-exist': 'default', 'key': 'value'}
有没有相当于Ruby哈希? 如果没有,Ruby中的惯用方法是什么?
哈希可以具有默认值或默认值Proc(当密钥不存在时调用)。
h = Hash.new("hi")
puts h[123] #=> hi
# change the default:
h.default = "ho"
在上面的情况下,哈希保持为空。
h = Hash.new{|h,k| h[k] = []}
h[123] << "a"
p h # =>{123=>["a"]}
Hash.new([])
不会起作用,因为每个键都使用相同的数组(与相同的对象相同)。
不要在这里击败死马,但setDefault的行为更像是对散列的提取。 它的行为与默认对哈希的作用方式不同。 在哈希上设置默认值后,任何缺少的键都将使用该默认值。 setDefault不是这种情况。 它仅存储一个缺失密钥的值,并且仅在找不到该密钥时才存储。 整个存储新的键值对是它与fetch的不同之处。
与此同时,我们目前正在做setDefault这样做:
h = {}
h['key'] ||= 'value'
Ruby继续开车回家:
h.default = "Hey now"
h.fetch('key', 'default') # => 'value'
h.fetch('key-doesnt-exist', 'default') # => 'default'
# h => {'key' => 'value'}
h['not your key'] # => 'Hey now'
蟒蛇:
h = {'key':'value'}
h.setdefault('key','default') # => 'value'
h.setdefault('key-doesnt-exist','default') # => 'default'
# h {'key': 'value', 'key-doesnt-exist': 'default'}
h['not your key'] # => KeyError: 'not your key'
Python中没有与此函数等效的东西。 您始终可以使用猴子修补来获得此功能:
class Hash
def setdefault(key, value)
if self[key].nil?
self[key] = value
else
self[key]
end
end
end
h = Hash.new
h = { 'key' => 'value' }
h.setdefault('key', 'default')
# => 'value'
h.setdefault('key-doesnt-exist', 'default')
# => 'default'
但请记住,猴子修补通常被视为禁忌,至少在某些代码环境中如此。
猴子补丁的黄金法则适用:只因为你可以,并不意味着你应该。
更惯用的方法是通过传递一个额外的块或值来通过Hash构造函数定义默认值。
您只需将块传递给Hash
构造函数 :
hash = Hash.new do |hash, key|
hash[key] = :default
end
当尝试访问不存在的密钥时,将调用该块。 它将传递哈希对象和密钥。 你可以随心所欲地做任何事情; 将密钥设置为默认值,从密钥中派生新值等。
如果您已有Hash
对象,则可以使用default_proc=
方法 :
hash = { key: 'value' }
# ...
hash.default_proc = proc do |hash, key|
hash[key] = :default
end
如果你只想修改setdefault
返回的值,你可以通过Hash#merge!
来表达这个Hash#merge!
:
蟒蛇:
>>> d = {}
>>> d.setdefault("k", []).append("v")
>>> d
{'k': ['v']}
红宝石:
[28] pry(main)> h = {}
=> {}
[29] pry(main)> h.merge!(k: [:v]) { |_key, old, new| old.concat(new) }
=> {:k=>[:v]}
[30] pry(main)> h
=> {:k=>[:v]}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.