我正在将我的PHP代码迁移到Ruby,在某些时候我需要更新循环内的哈希元素。例如:
compositions.each_pair do |element,params|
params['composition'].each_pair do |item,data|
data['af'] /= params['af sum']
data['mf'] /= params['mass']
end
end
我可以使用项目索引来制作它,但它会很难看。有没有一种很好的方法将循环变量链接到相应的哈希项?在PHP中,我会在相应的循环中编写&$params
和&$data
。或者可能是一个更好的建议?
更新
两个测试来证明这个问题。第一个:
a={'a'=>1, 'b'=>2, 'c'=>3}
a.each_pair do |k,v|
v += 1
end
p a # => {"a"=>1, "b"=>2, "c"=>3}
和第二个
a.each_pair do |k,v|
a[k] += 1
end
p a # => {"a"=>2, "b"=>3, "c"=>4}
UPDATE2
感谢Mladen(见下文),我理解了这两种情况之间的区别。但是,我仍然有一个问题:如何更新data
项目(不仅仅是自己的项目)?假设我们添加
data = data['af'] + data['mf']
到内循环。
答案 0 :(得分:2)
似乎该问题的代码可以正常工作:
compositions = {1 => {'af sum' => 100.0, 'mass' => 200.0, 'composition' => {1 => {'af' => 5.0, 'mf' => 6.0}, 2 => {'af' => 7.0, 'mf' => 8.0}, 3 => {'af' => 9.0, 'mf' => 16.0}}}}
#=> {1=>{"af sum"=>100.0, "mass"=>200.0, "composition"=>{1=>{"af"=>5.0, "mf"=>6.0}, 2=>{"af"=>7.0, "mf"=>8.0}, 3=>{"af"=>9.0, "mf"=>16.0}}}}
compositions.each_pair do |element,params|
params['composition'].each_pair do |item,data|
data['af'] /= params['af sum']
data['mf'] /= params['mass']
end
end
#=> {1=>{"af sum"=>100.0, "mass"=>200.0, "composition"=>{1=>{"af"=>0.05, "mf"=>0.03}, 2=>{"af"=>0.07, "mf"=>0.04}, 3=>{"af"=>0.09, "mf"=>0.08}}}}
但是示例结构几乎是从代码中猜到的,OP应该发布一个他正在使用的示例,这样我们才能真正取得一些进展。
编辑:
对整数执行+
方法时,会返回一个新对象。该对象在第一个示例中分配给v
,但未分配回哈希值,因此不会保留。在第二个示例中,将其分配回哈希值。
但是,如果使用变异方法,则可以就地更改对象,因此不需要将它们重新分配给哈希。例如:
{1 => 'foo', 2 => 'bar'}.each{|k,v| v.swapcase!}
#=> {1=>"FOO", 2=>"BAR"}
但
{1 => 'foo', 2 => 'bar'}.each{|k,v| v = 'baz'}
#=> {1=>"foo", 2=>"bar"}
编辑2:
我认为您在了解示例中的k
和v
时遇到了问题。它们只是块中的局部变量,它们首先引用散列中的任何内容,但它们引用的内容可以在块的过程中更改,就像使用任何其他变量一样。这种变化不会反映出哈希值。您需要更改对象,而不是对它的引用,才能实际更改它。
看看这个,更简单的例子,没有哈希,阻止mumbo-jumbo:
a = 5
b = a
b += 1
a # => 5
b # => 6
就这么简单。