Ruby - 循环遍历一个数组,附加一个hash-odd行为

时间:2012-04-23 12:49:22

标签: ruby arrays hashmap

当我循环浏览数组时,我对数组的更新方式感到困惑。这是一个显示行为的组成示例。

people = [{"name"=>"Edward", "age" =>"43", "height"=>"tallish"},
          {"name"=>"Ralph", "age" =>"40", "height"=>"medium heigth"},
          {"name"=>"George", "age" =>"35", "height"=>"very tall"},
          {"name"=>"Mark", "age" =>"25", "height"=>"short"}]
numbers = ["1","3","26"]
new_array = []

numbers.each do |number|
    people.each do |person|
        person["name"] = person["name"] +" "+ number
        new_array << person
    end
end

在new_array结束时

[{"name"=>"Edward 1 3 26", "age"=>"43", "height"=>"tallish"},
{"name"=>"Ralph 1 3 26", "age"=>"40", "height"=>"medium heigth"},
{"name"=>"George 1 3 26", "age"=>"35", "height"=>"very tall"},
{"name"=>"Mark 1 3 26", "age"=>"25", "height"=>"short"},
{"name"=>"Edward 1 3 26", "age"=>"43", "height"=>"tallish"},
{"name"=>"Ralph 1 3 26", "age"=>"40", "height"=>"medium heigth"},
{"name"=>"George 1 3 26", "age"=>"35", "height"=>"very tall"},
{"name"=>"Mark 1 3 26", "age"=>"25", "height"=>"short"},
{"name"=>"Edward 1 3 26", "age"=>"43", "height"=>"tallish"},
{"name"=>"Ralph 1 3 26", "age"=>"40", "height"=>"medium heigth"},
{"name"=>"George 1 3 26", "age"=>"35", "height"=>"very tall"},
{"name"=>"Mark 1 3 26", "age"=>"25", "height"=>"short"}]

每个人出现三次,这是我所期望和想要的。但每次他们的名字都是一样的。我希望名称第一次为"Edward 1",然后是"Edward 1 3",最后是"Edward 1 3 26"

这里发生了什么?我认为循环会将每个单独的哈希附加到new_array,而不是3都相同。

2 个答案:

答案 0 :(得分:1)

people.eachpeople提供了对每个条目的引用,因此当您执行person["name"] =...时,您正在修改原始数组。

试试这个:

numbers.each do |number|
    people.each do |person|
        new_person = person.dup
        new_person["name"] << " " + number
        new_array << new_person
    end
end

答案 1 :(得分:0)

您可以稍微转换代码以查看过程

numbers.each do |number|
    people.each do |person|
        person["name"] = person["name"] +" "+ number
        new_array << person
        puts person["name"]
    end
end

你会得到这个结果:

Edward 1
...
Edward 1 3
...
Edward 1 3 26
...

正如您所看到的,算法的工作方式几乎与您预期的一样。但person["name"]仅引用一个对象(字符串),这就是为什么最终结果具有最后一个字符串Edward 1 3 26

编辑:为了获得您想要的内容,您应该每次创建新对象

numbers.each do |number|
  people.each do |person|
    person["name"] = person["name"] +" "+ number
    new_array << person.dup
  end
end

不要忘记重新初始化people变量,因为这个表达式

person["name"] = person["name"] +" "+ number

修改人物变量。