Reputation: 3499
I'm confused about the way an array is updated when I loop through it. Here's a made up example that shows the behaviour.
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
At the end of that new_array is
[{"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"}]
Each person appears three times, which I what I expected and wanted. BUT their name is the same each time. I expected name to be "Edward 1"
the first time, then "Edward 1 3"
and finally "Edward 1 3 26"
What's going on here? I thought the loop would append each separate hash onto new_array, rather than 3 all the same.
Upvotes: 1
Views: 1014
Reputation: 21791
You can convert your code a little bit to see the process
numbers.each do |number|
people.each do |person|
person["name"] = person["name"] +" "+ number
new_array << person
puts person["name"]
end
end
You will get this result:
Edward 1
...
Edward 1 3
...
Edward 1 3 26
...
As you can see the algorithm works almost as you expected. But person["name"]
is reference to only one object(string), that's why the final result has the last string Edward 1 3 26
EDIT: To get your what you wanted you should create new object every time
numbers.each do |number|
people.each do |person|
person["name"] = person["name"] +" "+ number
new_array << person.dup
end
end
Don't forget reinitialize the people variable because this expression
person["name"] = person["name"] +" "+ number
modifies the people variable.
Upvotes: 0
Reputation: 46667
people.each
is providing you with a reference to each entry in people
, so when you do person["name"] =...
you're modifying the original array.
Try this:
numbers.each do |number|
people.each do |person|
new_person = person.dup
new_person["name"] << " " + number
new_array << new_person
end
end
Upvotes: 1