Ruby 默认哈希值&;阵列视差
这是一个密码Ruby 默认哈希值&;阵列视差,ruby,arrays,hashmap,Ruby,Arrays,Hashmap,这是一个密码 irb(main):085:0> h = Hash.new([]) => {} irb(main):086:0> h['a'] = 'sdfds' => "sdfds" irb(main):087:0> h => {"a"=>"sdfds"} irb(main):088:0> h['b'].push(h['a'] )
irb(main):085:0> h = Hash.new([])
=> {}
irb(main):086:0> h['a'] = 'sdfds'
=> "sdfds"
irb(main):087:0> h
=> {"a"=>"sdfds"}
irb(main):088:0> h['b'].push(h['a'] )
=> ["sdfds"]
irb(main):089:0> h
=> {"a"=>"sdfds"}
irb(main):090:0> h['b']
=> ["sdfds"]
irb(main):091:0> h['c']
=> ["sdfds"]
irb(main):092:0> h
=> {"a"=>"sdfds"}
我想做的是让h[b]像一个普通的数组一样工作。然而,发生的是h[b]和h[c]现在有了一个新的默认值。我期望h[b]有这个新值,但看起来push实际上并没有推到一个不存在的值
然后打印h实际上只显示h[a]
为什么会这样?虽然ruby被广泛使用,但这确实不值得一试,但这些都是可能不受欢迎的特殊行为。而且它因人而异
更新
然而,正确的行为并没有显示出任何可疑之处:
irb(main):104:0> h = Hash.new([])
=> {}
irb(main):105:0> h['a'] = [1,2,3,'dsfds']
=> [1, 2, 3, "dsfds"]
irb(main):106:0> h['b'] += h['a']
=> [1, 2, 3, "dsfds"]
irb(main):107:0> h
=> {"a"=>[1, 2, 3, "dsfds"], "b"=>[1, 2, 3, "dsfds"]}
另一种意想不到的令人困惑的行为
irb(main):093:0> h = [1,2,3]
=> [1, 2, 3]
irb(main):094:0> h.shift(0)
=> []
irb(main):095:0> h
=> [1, 2, 3]
irb(main):096:0> h.unshift(0)
=> [0, 1, 2, 3]
irb(main):097:0> h.shift(10)
=> [0, 1, 2, 3]
irb(main):098:0> h.shift(90)
=> []
irb(main):099:0> h
=> []
irb(main):100:0> h = [1,2,3]
=> [1, 2, 3]
irb(main):101:0> h.shift(100)
=> [1, 2, 3]
irb(main):102:0> h
=> []
irb(main):103:0> h.shift(90)
=> []
如果你不感到惊讶,我甚至不会在这里问这个问题,但是我想读一些关于这种奇怪行为的解释。让我想到是否应该在生产环境中使用它。
如果该散列随后被与散列项不对应的键访问,则返回的值取决于用于创建散列的new的样式。在第一种形式中,访问返回nil
。如果指定了obj
,则此单个对象将用于所有默认值
在这里,您为h
创建了一个哈希对象,默认值为所有不存在的键的相同数组
h = Hash.new([])
h # => {:a=>10}
现在你打电话来了。因此键:一个添加到散列中的,与之关联的值为10
h[:a] = 10
只有在调用hash#[]=
时,才会将密钥添加到哈希中,但您的h[:b]
与相同。因此,:b
不是作为键添加的,而是返回您设置的默认数组,行h=Hash.new([])
。因此,h[:b]
实际上会返回默认数组,并在其上调用array#push
方法
h[:b].push(11)
因此,根据上面的解释,您无法在哈希h
中看到键:b
h = Hash.new([])
h # => {:a=>10}
h[:b].push(11)
导致默认数组现在只有元素,即[11]
。因此,现在h[:c]
返回默认数组,即[11]
h[:c] # => [11]
实际上意味着array.slice!(0,n)
。现在告诉我们-删除由索引(可以选择最长的元素)或范围给定的元素。返回已删除的对象,如果索引超出范围,则返回nil
为什么h.shift(0)#=>[]
根据文件shift(n)→ new_ary
,如果传递参数,则将以数组形式获得结果。现在您提供了0
,这意味着您不希望从h
中删除任何元素。因此,根据定义,您得到了一个空数组
请看下面的代码:
(arup~>~)$ pry --simple-prompt
>> h = [1,2,3]
=> [1, 2, 3]
>> h.shift(10)
=> [1, 2, 3]
>> h
=> []
现在再看一遍医生h.shift(10)
为您提供了[1,2,3]
,这是一个3元素数组,同时也从h
中删除了元素。因此,最后一个h
将为您提供[]
这里,h['b']+=h['a']
实际上意味着,h['b']=h['b']+h['a']
。现在您的散列没有键'b'
,因此h['b']
将为您提供默认数组[]
。现在,行h['b']=h['b']+h['a']
变成h[b]=[]+[1,2,3,'dsfds']
。现在[]+[1,2,3,'dsfds']
将为您提供[1,2,3,'dsfds']
,这只是一个方法调用。最后,h['b']+=h['a']
是一个简单的Hash方法调用,因此键“b”
被添加到Hashh
,值为[1,2,3,'dsfds']
。现在h['a']
和h['b']
显示相同的数组,但是否,这些数组不是相同的数组对象,但是是,它们包含相同的元素记住数组#+
创建了一个新的数组对象。
如果该散列随后被与散列项不对应的键访问,则返回的值取决于用于创建散列的new的样式。在第一种形式中,访问返回nil
。如果指定了obj
,则此单个对象将用于所有默认值
在这里,您为h
创建了一个哈希对象,默认值为所有不存在的键的相同数组
h = Hash.new([])
h # => {:a=>10}
现在你打电话来了。因此键:一个添加到散列中的,与之关联的值为10
h[:a] = 10
只有在调用hash#[]=
时,才会将密钥添加到哈希中,但您的h[:b]
与相同。因此,:b
不是作为键添加的,而是返回您设置的默认数组,行h=Hash.new([])
。因此,h[:b]
实际上会返回默认数组,并在其上调用array#push
方法
h[:b].push(11)
因此,根据上面的解释,您无法在哈希h
中看到键:b
h = Hash.new([])
h # => {:a=>10}
h[:b].push(11)
导致默认数组现在只有元素,即[11]
。因此,现在h[:c]
返回默认数组,即[11]
h[:c] # => [11]
实际上意味着array.slice!(0,n)
。现在告诉我们-删除由索引(可以选择最长的元素)或范围给定的元素。返回已删除的对象,如果索引超出范围,则返回nil
为什么h.shift(0)#=>[]
根据文件shift(n)→ new_ary
,如果传递参数,则将以数组形式获得结果。现在您提供了0
,这意味着您不希望从h
中删除任何元素。因此,根据定义,您得到了一个空数组
请看下面的代码:
(arup~>~)$ pry --simple-prompt
>> h = [1,2,3]
=> [1, 2, 3]
>> h.shift(10)
=> [1, 2, 3]
>> h
=> []
现在再看一遍医生<代码>h.shift(10)
为您提供[1,2,3]
,w