PascalTurbo PascalTurbo - 6 months ago 9
Ruby Question

Modifying array of hashes inside an iterator only modifies the last item

I have a array of hashes and i wan't to modify each single hash. So I'm iterating over my source data - in this example simply iterate over numbers and I modify each hash.
But outside the context of the iterator, only one element of the array was modified instead of all elements and the first element of the array was overridden by the last element.

arr = [{ id: 1 }, { id: 2 }, { id: 3 }]

1.upto(3) do |i|
a = arr.detect { |t| t[:id] = i }
a[:content] = 'this is my content'
end

puts arr


Output

{:id=>3, :content=>"this is my content"}
{:id=>2}
{:id=>3}


Expected Output

{:id=>1, :content=>"this is my content"}
{:id=>2, :content=>"this is my content"}
{:id=>3, :content=>"this is my content"}

Answer

Use map or each:

arr = [{ id: 1 }, { id: 2 }, { id: 3 }]
arr.map { |e| e.merge(content: 'this is my content')}
=> [{:id=>1, :content=>"this is my content"}, 
    {:id=>2, :content=>"this is my content"}, 
    {:id=>3, :content=>"this is my content"}]

Or you can replace == with = in your code:

a = arr.detect { |t| t[:id] == i }

== - equality, = - assignment

Comments