为什么Hash.new({})隐藏hash成员? [英] Why does Hash.new({}) hide hash members?

查看:127
本文介绍了为什么Hash.new({})隐藏hash成员?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好的,所以我想创建一个哈希值为空的哈希值作为默认值。有点奇怪,我知道,但让我们说,我认为它可能是有用的。



所以我做了这些:

 >> a = Hash.new({})
=> {}
>> a [:a] [:b] = 5
=> 5
>> a
=> {}
>> a [:a]
=> {:b => 5}
>> a.keys
=> []
>> a.size
=> 0
>> a [:a] .size
=> 1

换句话说,当我检查散列时,我看不到散列成员,但我可以访问它的钥匙。



这是预期的行为吗?这里发生了什么?



顺便说一句,这是Ruby 1.9.1,还没有尝试过早期版本。



<编辑:简单的例子,因为它不一定是散列哈希散列...

解决方案

它是预期的行为(跨所有ruby版本)。如果你进一步尝试一下,你会发现你总是访问相同的哈希,无论你使用哪个键:

 >> a [:a] [:b] = 1 
=> 1
>> a [:c] [:d] = 2
=> 2
>> a [:d]
=> {:b => 1,:d => 2}

默认参数的作用是:如果你执行 hash [key] ,它会检查该密钥是否存在于散列中。如果是,则返回该密钥的值。如果不是,则返回默认值。它不会将密钥添加到散列中,并且每次都会返回相同的默认对象(不是副本)。



要获得所需内容,您需要指定一个默认的块代替。这样,每次访问不在散列中的密钥时都会执行该块。在块内部,您可以创建一个新的哈希,并将该关键点设置为指向该哈希。像这样:

  Hash.new {| h,k | h [k] = {}} 


Ok, so I wanted to create a hash which has an empty hash as the default value. A bit weird, I know, but let's say that I thought it might be useful.

So here's what I did:

>> a = Hash.new({})
=> {}
>> a[:a][:b] = 5
=> 5
>> a
=> {}
>> a[:a]
=> {:b=>5}
>> a.keys
=> []
>> a.size
=> 0
>> a[:a].size
=> 1

In other words, I don't see hash member when I inspect the hash, but I can access it by its key.

Is this expected behavior? What is going on here?

BTW, this is Ruby 1.9.1, haven't tried earlier versions.

Edit: simplified example as it doesn't have to be a hash of hashes of hashes...

解决方案

It is expected behaviour (across all ruby versions). And if you experiment a bit further, you'll see that you always access the same hash, no matter which key you use:

>> a[:a][:b] = 1
=> 1
>> a[:c][:d] = 2
=> 2
>> a[:d]
=> {:b=>1, :d=>2}

The way Hash.new with a default argument works is: If you do hash[key] it checks whether that key exists in the hash. If it does, it returns the value for that key. If not it returns the default value. It does not add the key to the hash and it will return the same default object (not a copy) every time.

To get what you want, you want to specify a default block instead. That way, the block will be executed every time you access a key that is not in the hash. Inside the block you can create a new Hash and set the key to "point" to that hash. Like so:

Hash.new { |h,k|  h[k] = {} }

这篇关于为什么Hash.new({})隐藏hash成员?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆