如何分配 hash['a']['b']= 'c'如果 hash['a'] 不存在?

发布于 2024-11-05 02:54:06 字数 137 浏览 0 评论 0原文

有没有比更简单的方法

if hash.key?('a')
  hash['a']['b'] = 'c' 
else  
  hash['a'] = {}
  hash['a']['b'] = 'c' 
end

Is there any way simpler than

if hash.key?('a')
  hash['a']['b'] = 'c' 
else  
  hash['a'] = {}
  hash['a']['b'] = 'c' 
end

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

无风消散 2024-11-12 02:54:06

最简单的方法是使用块参数构造哈希

hash = Hash.new { |h, k| h[k] = { } }
hash['a']['b'] = 1
hash['a']['c'] = 1
hash['b']['c'] = 1
puts hash.inspect
# "{"a"=>{"b"=>1, "c"=>1}, "b"=>{"c"=>1}}"

new 表单创建一个新的空哈希作为默认值。您不希望这样:

hash = Hash.new({ })

因为这将为所有默认条目使用完全相同哈希。

另外,正如 Phrogz 所指出的,您可以使用 default_proc

hash = Hash.new { |h, k| h[k] = Hash.new(&h.default_proc) }

更新:我想我应该澄清我对 Hash.new({ }) 的警告。当你这样说时:

h = Hash.new({ })

这很像这样说:

h = Hash.new
h.default = { }

然后,当你访问 h 将某些内容分配为 h[:k][:m] = y 时,它行为就好像您这样做了:

if(h.has_key?(:k))
    h[:k][:m] = y
else
    h.default[:m] = y
end

然后,如果您 h[:k2][:n] = z,您最终将分配 h.default[:n] = z< /代码>。请注意,h 仍然表示 h.has_key?(:k) 为 false。

但是,当您这样说时:

h = Hash.new(0)

一切都会顺利进行,因为您永远不会在此处修改 h[k] ,您只会从 h 读取一个值(其中如果需要,将使用默认值)或为 h 分配一个新值。

The easiest way is to construct your Hash with a block argument:

hash = Hash.new { |h, k| h[k] = { } }
hash['a']['b'] = 1
hash['a']['c'] = 1
hash['b']['c'] = 1
puts hash.inspect
# "{"a"=>{"b"=>1, "c"=>1}, "b"=>{"c"=>1}}"

This form for new creates a new empty Hash as the default value. You don't want this:

hash = Hash.new({ })

as that will use the exact same hash for all default entries.

Also, as Phrogz notes, you can make the auto-vivified hashes auto-vivify using default_proc:

hash = Hash.new { |h, k| h[k] = Hash.new(&h.default_proc) }

UPDATE: I think I should clarify my warning against Hash.new({ }). When you say this:

h = Hash.new({ })

That's pretty much like saying this:

h = Hash.new
h.default = { }

And then, when you access h to assign something as h[:k][:m] = y, it behaves as though you did this:

if(h.has_key?(:k))
    h[:k][:m] = y
else
    h.default[:m] = y
end

And then, if you h[:k2][:n] = z, you'll end up assigning h.default[:n] = z. Note that h still says that h.has_key?(:k) is false.

However, when you say this:

h = Hash.new(0)

Everything will work out okay because you will never modified h[k] in place here, you'll only read a value from h (which will use the default if necessary) or assign a new value to h.

傲鸠 2024-11-12 02:54:06

一个简单的,但 hash 应该是一个有效的 hash 对象

(hash["a"] ||= {})['b'] = "c"

a simple one, but hash should be a valid hash object

(hash["a"] ||= {})['b'] = "c"
爱已欠费 2024-11-12 02:54:06

如果您按如下方式创建 hash ,并使用新的(相同默认值)哈希的默认值:(感谢 Phrogz 的更正;我的语法错误)

hash = Hash.new{ |h,k| h[k] = Hash.new(&h.default_proc) }

那么您

hash["a"]["b"] = "c"

无需任何额外的操作 即可完成代码。

If you create hash as the following, with default value of a new (identically default-valued) hash: (thanks to Phrogz for the correction; I had the syntax wrong)

hash = Hash.new{ |h,k| h[k] = Hash.new(&h.default_proc) }

Then you can do

hash["a"]["b"] = "c"

without any additional code.

鼻尖触碰 2024-11-12 02:54:06

这里的问题是:
Ruby 中是否可以像 PHP 中那样自动初始化多维哈希数组?
提供了一个非常有用的 AutoHash 实现来执行此操作。

The question here:
Is auto-initialization of multi-dimensional hash array possible in Ruby, as it is in PHP?
provides a very useful AutoHash implementation that does this.

鲸落 2024-11-12 02:54:06
class NilClass
  def [](other)
    nil
  end
end

一旦你定义了它,一切都会自动进行。但请注意,从现在开始,nil 在用作哈希时将表现为空哈希。

class NilClass
  def [](other)
    nil
  end
end

Once you defined that, everything will work automatically. But be aware that from now on nil would behave as an empty hash when used as a hash.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文