Reputation: 3258
I give up, I have no idea why the hashes I'm creating are not being added to the end of the array. When I pp
the hash it is correct, but for some reason the first hash is getting duplicated, while the second hash isn't being added..
The result I'm getting is this:
[{:id=>"36757153479", :quantity=>1, :status=>"new"},
{:id=>"36757153479", :quantity=>1, :status=>"new"}]
#notice that the id is the same
While what I want is this:
[{:id=>"36767751239", :quantity=>1, :status=>"new"},
{:id=>"36757153479", :quantity=>1, :status=>"new"}]
The incoming array looks like this:
me = [{"id"=>36767751239, "quantity"=>1,"vendor"=>"Martha
Stewart", "product_id"=>9707911431, "gift_card"=>false}, {"id"=>36757153479,
"quantity"=>1, "vendor"=>"Naturalizer", "product_id"=>9707504007,
"gift_card"=>false}]
And my code that steps thru it is this:
incoming_cart_array = []
incoming_cart_hash = {}
unless me.nil?
me.each do |product|
incoming_cart_hash[:id] = product['variant_id'].to_s
incoming_cart_hash[:quantity] = product['quantity']
incoming_cart_hash[:status] = "new"
incoming_cart_array << incoming_cart_hash
end
end
I've done this sort of thing 100's of times, but somehow this isn't working. Its probably something right in front of me, I just can't see it.
Thanks
Upvotes: 1
Views: 37
Reputation: 27813
Your code creates only one {}
ever, so you get an array with n
times the same hash.
You must create a new {}
for each iteration.
incoming_cart_array = []
unless me.nil?
me.each do |product|
incoming_cart_hash = {}
...
end
end
Pro tipp — best practice in Ruby is to use map
to create and array from an array. And you can use literal syntax to create a new hash, and use &&
to check for the nil
case.
incoming_cart_array = me && me.map do | product |
{
id: product['id'].to_s,
quantity: product['quantity'],
status: "new",
}
end
Upvotes: 1
Reputation: 3454
I seemed to be able to solve it as
incoming_cart_array = []
unless me.nil?
me.each do |product|
incoming_cart_hash = {}
incoming_cart_hash[:id] = product['id'].to_s
incoming_cart_hash[:quantity] = product['quantity']
incoming_cart_hash[:status] = "new"
incoming_cart_array << incoming_cart_hash
end
end
However, I cannot seem to find the reason, that it cannot overwrite incoming_cart_hash[:id] when it isn't defined in the same scope. I'll dig into it, and update my answer if I figure it out!
Edit: My first initial though after a little debugging is, that when the hash isn't a local variable, it's defined (In the Ruby Source, which is C-based), as a pointer to the hash-type. Therefore in the array << hash
line, you're inserting a pointer to the hash in the array. When you're running me.each
n-times (2 in this case), the hash is updated, thus you'll have n
-pointers in the array, all pointing to the same element. The hash which you're updating. It's seen as the same ruby object.
If you're outputting incoming_cart_hash.object_id
inside the loop, each time, you'll see that the object_id is the same every time, when the hash-definition is outside the loop. However, when it's inside - defined as a new local variable every time, it'll differ, as it is a new and redefined object every time.
I found a bit of notes about it here: Ruby - Parameters by reference or by value?
Upvotes: 3