Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ionic-framework/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 哈希值与`<;之间的交互<;`操作人员_Ruby_Hash - Fatal编程技术网

Ruby 哈希值与`<;之间的交互<;`操作人员

Ruby 哈希值与`<;之间的交互<;`操作人员,ruby,hash,Ruby,Hash,我期望: h = Hash.new([]) h['a'] << 'b' h['a'] << 'c' h # => {} 我正在寻找一个解释,解释它为什么不工作,以及如何以最佳方式工作。这是因为您修改了作为默认值传递的特定对象。因此: h = Hash.new([]) h['a'] << 'b' h['a'] << 'c' h['b'] # or h['a'] or h[:virtually_anything] # => ["b", "

我期望:

h = Hash.new([])
h['a'] << 'b'
h['a'] << 'c'
h # => {}

我正在寻找一个解释,解释它为什么不工作,以及如何以最佳方式工作。

这是因为您修改了作为默认值传递的特定对象。因此:

h = Hash.new([])
h['a'] << 'b'
h['a'] << 'c'
h['b'] # or h['a'] or h[:virtually_anything]
# => ["b", "c"]
h=Hash.new([])

h['a']这是因为
h
没有键
'a'
,您需要在重置之前对其进行初始化,否则它只是一个默认值:

h = Hash.new([])
h['a'] = ['b']
h['a'] << 'c'

h['a'] #=> ["b", "c"]
h #=> {"a"=>["b", "c"]}
正如Sergio Tulentsev所解释的,()这创建了“动态”键,请尝试以下方法:

k = Hash.new {|h, k| puts "Just created a new key: #{k}"; h[k] = [] }
p k['a'] << 'a'
p k['a'] << 'a'
p k['b'] << 'b'
p k
k=Hash.new{h,k | puts“刚刚创建了一个新密钥:{k}”;h[k]=[]

p k['a']行不起作用的原因是,在访问缺少的键时,只返回默认值(无论您指定了什么),而不将其分配给键。由于您的默认值是一个复杂的可变对象(每次返回的对象都是同一个对象),因此您得到了您观察到的结果:所有值都被直接推到默认值中,绕过散列。这可能是哈希和可变默认值最常见的错误

要执行所需操作,请使用第三种形式的Hash.new

new {|hash, key| block } → new_hash
比如像这样

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

经过测试,看起来很奇怪,如果你得到详细信息,请更新。你需要什么详细信息?这已经很奇怪了……对上述奇怪事情的澄清:)我想这就是答案的意义;)默认值只是当键不存在时的默认返回值。它与键值赋值无关@SergioTulentsev已经向您展示了如何“让它工作”不应该
array,即不应该
h['a']不,没有理由这样做。这都是关于您当前正在修改的对象。当你在做
h['a']=['b']
时,你正在创建一个新的
数组
对象,并将其分配给
'a'
键,输入
h
哈希值。@gorn:“但默认值不应该自动执行吗?”-有人可能认为这是一个明智的方法。唉,散列文档中的措辞相当明确。“检索键对象对应的值对象。如果找不到,则返回默认值”@gorn:这是您对这两个对象如何工作的误解。后者重新分配数组。这就是关键的区别。我认为
array@gorn:不,不是。当然不是,但根据文档@gorn:“它还将x作为数组的最后一个元素)”-不完全是。它创建一个新数组,而不是就地修改现有数组。但是我们将
[]
作为new的参数传递,而不是作为块代码传递。你能详细说明一下吗?@ray:是的,这种设置默认值的方式对可变对象(这里是数组)不起“预期”的作用@SergioTulentsevI已经详细说明了答案,因此它对其他人更有用,如果你愿意的话,请进行更正。明确说明:“如果需要,块负责将值存储在散列中。”@Stefan你是对的,尽管它似乎更倾向于“块”样式。
new {|hash, key| block } → new_hash
h = Hash.new {|h, k| h[k] = [] }