繁体   English   中英

Ruby散列等价于Python dict setdefault

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM