【问题标题】:Ruby - looping through an array, appending a hash - odd behaviourRuby - 遍历数组,附加哈希 - 奇怪的行为
【发布时间】:2012-04-23 12:49:22
【问题描述】:

我对循环遍历数组时的更新方式感到困惑。这是一个显示行为的虚构示例。

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"}]

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

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

【问题讨论】:

  • 你真正想要什么输出?可能有一个简单的非迭代解决方案。
  • @Mark Thomas - 我真的希望每个带有 name 元素的哈希都更改了几次。

标签: ruby arrays hashmap


【解决方案1】:

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

试试这个:

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

【讨论】:

  • new_array 最终还是和以前一样!我想现在 new_person 是一个更新的参考。
  • ……嗯。我没想到。我会尝试进一步挖掘 - 这真的应该是可能的。
  • 查看 megas 的回答 - 您只需将 .dup 放在早期
  • 但他的回答仍然会编辑原始的people 数组...确定吗?
  • 抱歉,我的问题不太清楚 - 我对原始数组并不特别在意,但我在 new_array 中得到了什么。
【解决方案2】:

你可以稍微转换一下你的代码来看看这个过程

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

修改人员变量。

【讨论】:

  • 感谢您的解释,但我怎样才能得到我想要的 - 一个具有不同名称的数组?
猜你喜欢
  • 1970-01-01
  • 2014-12-30
  • 1970-01-01
  • 2013-11-25
  • 1970-01-01
  • 2014-11-21
  • 1970-01-01
  • 2016-09-03
相关资源
最近更新 更多