Reputation: 299
I want to insert multiple hashes into an array which will create an array of hashes. But every time I add a new hash to the array, it would overwrite the previous ones. Any idea what is going on?
partArray = []
partHash = {}
partHash["name"] = "Item1"
partHash["owner"] = "Item1"
#Insert first hash into array
partArray << partHash
puts partArray
#new set of key, value pairs
#to be appended to array
partHash["name"] = "Item2"
partHash["owner"] = "Item2"
#Append second hash into array
partArray << partHash
puts partArray
output :
{"name"=>"Item1", "owner"=>"Item1"}
new Array is :
{"name"=>"Item2", "owner"=>"Item2"}
{"name"=>"Item2", "owner"=>"Item2"}
I'm not sure why the values in the first hash were overwritten. Any help is appreciated.
Upvotes: 2
Views: 2971
Reputation: 9497
I'm not sure why the values in the first hash were overwritten?
Firstly we define an empty array and an empty hash.
partArray = []
partHash = {}
Now we create two new key-value pairs in our hash. Because these keys don't currently exist within partHash
, they are created for you.
partHash["name"] = "Item1"
partHash["owner"] = "Item1"
parthHash #{"name"=>"Item1", "owner"=>"Item1"}
Insert our hash into our array:
partArray << partHash
partArray #[{"name"=>"Item1", "owner"=>"Item1"}]
Here is the key step. Because the keys "name"
and "owner"
already exist within the hash, the []=
notation will simply redefine any existing values, so.
partHash["name"] = "Item2"
partHash["owner"] = "Item2"
partHash # {"name"=>"Item2", "owner"=>"Item2"}
partArray #[{"name"=>"Item2", "owner"=>"Item2"}]
Currently partArray
contains a single partsHash
hash. Finally you append partHash
into partArray
again:
partArray << partHash
partArray #[{"name"=>"Item2", "owner"=>"Item2"}, {"name"=>"Item2", "owner"=>"Item2"}]
Upvotes: 1
Reputation: 211590
You're saving the same hash in two different locations of the array. Think of Ruby as adding object references instead of copying the object each time you nest it inside another thing.
Do do this with different values, you might want to create a new one each time:
part_array = [ ]
part_array << {
# ... Hash entry
}
There are legitimate reasons why you might want to put the same thing in an array twice, it could be a way of saving memory when using a large data structure.
As a note, Ruby tends to strongly recommend variable names like part_array
, all lower-case. Likewise, for Hash keys, Symbols are often preferred since they're inexpensive internally.
Upvotes: 4