初始化Ruby Hash,如:
keys = [0, 1, 2]
hash = Hash[keys.each_with_object([]).to_a]
尝试将值插入键时,表现得很奇怪。
hash[0].push('a')
# will result into following hash:
=> {0=>["a"], 1=>["a"], 2=>["a"]}
我只是想插入一个键,但它正在更新所有键的值。
答案 0 :(得分:3)
是的,each_with_object
本身就非常奇怪。这不是应该如何使用的。问题出现了正是,因为你误用了它。
keys.each_with_object([]).to_a
# => [[0, []], [1, []], [2, []]]
你看,即使看起来这些数组是分开的,但在所有三种情况下它实际上都是相同的数组。这就是为什么如果你将一个元素推入一个元素,它会出现在所有其他元素中。
这是一个更好的方法:
h = keys.each_with_object({}) {|key, h| h[key] = []}
# => {0=>[], 1=>[], 2=>[]}
或者说,
h = keys.zip(Array.new(keys.size) { [] }).to_h
或许多其他方式。
如果您不关心具有这一组确切键的哈希,只是想要所有键将空数组作为默认值,那么这也是可能的。
h = Hash.new { |hash, key| hash[key] = [] }
答案 1 :(得分:0)
所有密钥引用相同的数组。
解释问题的简化版本:
a = []
b = a
a.push('something')
puts a #=> ['something']
puts b #=> ['something']
即使您有两个变量(a
和b
),也只有一个数组对象。因此,变量a
对数组引用的任何更改都将更改变量b
引用的数组 。因为它是同一个对象。
您要实现的目标的长版本将是:
keys = [1, 2, 3]
hash = {}
keys.each do |key|
hash[key] = []
end
更短的版本:
[1, 2 ,3].each_with_object({}) do |key, accu|
accu[key] = []
end
答案 2 :(得分:-1)
为什么要将它们放在一个数组中,然后将它们放入哈希?如果我理解你的问题,你可能想要这样做:
hash = {'1'=>"",'2'=>"",'3'=>""}
hash['1'] = 'a'
hash['2'] = 'b'
hash['3'] = 'Hello'
如果对象的类不满足您的要求,您可以在整数或任何您想要的之后转换它们! 希望能帮助到你!