代码之家  ›  专栏  ›  技术社区  ›  Andy

如何在该哈希的循环内更新Ruby哈希项?

  •  2
  • Andy  · 技术社区  · 14 年前

    我正在将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}
    

    更新2

    多亏了姆亚丁(见下文),我理解了这两种情况之间的区别。但是,我仍然有一个问题:如何更新 data 物品(不仅仅是它自己的物品)?假设我们加上

    data = data['af'] + data['mf']
    

    到内环。

    1 回复  |  直到 14 年前
        1
  •  2
  •   Mladen Jablanović    14 年前

    问题中的代码似乎工作正常:

    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 在这些例子中是。它们只是块中的局部变量,从引用哈希中的任何内容开始,但是它们引用的内容可以在块的过程中更改,就像使用任何其他变量一样。这种变化不会反映到散列值上。你需要改变 非常对象 不是对它的引用,而是对它的实际更改。

    看看这个,甚至更简单的例子,没有哈希,blocks-mumbo-jumbo:

    a = 5
    b = a
    b += 1
    a # => 5
    b # => 6
    

    就这么简单。