danynl
danynl

Reputation: 299

ruby - Inserting multiple hashes into an array in ruby

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

Answers (2)

Sagar Pandya
Sagar Pandya

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

tadman
tadman

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

Related Questions