Ruby 密钥被替换,而不是创建新密钥
Ruby key getting replaced, instead of a new key created
ruby 2.5
我有以下代码:
test = {'primer' => 'grey'}
layers = ["tan","burgundy"]
fillers = ["blue","yellow"]
layers.each do |l|
fillers.each do |f|
test[l] = {} if !test.respond_to?(l)
test[l][f] = {} if !test[l].respond_to?(f)
end
end
当我在 irb 中 运行 时,我得到以下信息:
{"primer"=>"grey", "tan"=>{"yellow"=>{}}, "burgundy"=>{"yellow"=>{}}}
我期待:
{"primer"=>"grey", "tan"=>{"blue"=>{},"yellow"=>{}}, "burgundy"=>{"blue"=>{},"yellow"=>{}}}
为什么第一个 respond_to 生成密钥,而第二个 respond_to 生成密钥,而第二个替换前一个密钥?
我错过了什么?
表达式
test.respond_to?(l)
没有意义。 l
是一个字符串,并且 respond_to?
returns 如果接收方具有此字符串表示的名称的方法则为真。由于接收者是一个 Hash 并且 Hash 没有方法 Hash#tan 和 Hash#burgundy,所以测试总是失败。
也许你想做一个 test.has_key?(l)
而不是....
假设您有散列 {a: 1}
,拥有键 :a
不会使散列对象响应 :a
。 hash.respond_to?(:a)
仍然会 return false
。你想检查一个密钥是否存在,这可以使用 has_key?
/key?
.
来完成
layers.each do |l|
fillers.each do |f|
test[l] = {} unless test.has_key?(l)
test[l][f] = {} unless test[l].has_key?(f)
end
end
但是,由于您将值设置为散列,这是一个真实值。您还可以使用 ||=
,它仅在当前值为假时才分配一个值。 test[:non_existing_key]
将导致 nil
(除非设置了默认值)。
表示以上可以替换为:
layers.each do |l|
fillers.each do |f|
test[l] ||= {}
test[l][f] ||= {}
end
end
您可以使用 product
来简化整个语句,它为您组合了两个循环。
layers.product(fillers) do |layer, filler|
test[layer] ||= {}
test[layer][filler] ||= {}
end
ruby 2.5
我有以下代码:
test = {'primer' => 'grey'}
layers = ["tan","burgundy"]
fillers = ["blue","yellow"]
layers.each do |l|
fillers.each do |f|
test[l] = {} if !test.respond_to?(l)
test[l][f] = {} if !test[l].respond_to?(f)
end
end
当我在 irb 中 运行 时,我得到以下信息:
{"primer"=>"grey", "tan"=>{"yellow"=>{}}, "burgundy"=>{"yellow"=>{}}}
我期待:
{"primer"=>"grey", "tan"=>{"blue"=>{},"yellow"=>{}}, "burgundy"=>{"blue"=>{},"yellow"=>{}}}
为什么第一个 respond_to 生成密钥,而第二个 respond_to 生成密钥,而第二个替换前一个密钥?
我错过了什么?
表达式
test.respond_to?(l)
没有意义。 l
是一个字符串,并且 respond_to?
returns 如果接收方具有此字符串表示的名称的方法则为真。由于接收者是一个 Hash 并且 Hash 没有方法 Hash#tan 和 Hash#burgundy,所以测试总是失败。
也许你想做一个 test.has_key?(l)
而不是....
假设您有散列 {a: 1}
,拥有键 :a
不会使散列对象响应 :a
。 hash.respond_to?(:a)
仍然会 return false
。你想检查一个密钥是否存在,这可以使用 has_key?
/key?
.
layers.each do |l|
fillers.each do |f|
test[l] = {} unless test.has_key?(l)
test[l][f] = {} unless test[l].has_key?(f)
end
end
但是,由于您将值设置为散列,这是一个真实值。您还可以使用 ||=
,它仅在当前值为假时才分配一个值。 test[:non_existing_key]
将导致 nil
(除非设置了默认值)。
表示以上可以替换为:
layers.each do |l|
fillers.each do |f|
test[l] ||= {}
test[l][f] ||= {}
end
end
您可以使用 product
来简化整个语句,它为您组合了两个循环。
layers.product(fillers) do |layer, filler|
test[layer] ||= {}
test[layer][filler] ||= {}
end