2

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.

2
  • 1
    perhaps this will shed some light: p partArray.map(&:object_id) Commented Sep 29, 2016 at 5:49
  • getting the same hash object_id, with different values. {"name"=>"Item1", "owner"=>"Item1"} [70094101888900] new Array is : {"name"=>"Item2", "owner"=>"Item2"} {"name"=>"Item2", "owner"=>"Item2"} [70094101888900, 70094101888900] Commented Sep 29, 2016 at 16:16

2 Answers 2

4

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.

Sign up to request clarification or add additional context in comments.

5 Comments

you mean reiniitialize the array and hash every time I want to add a new entry?
Only the hash, as that's the thing you're changing each time you insert it. If you changed the array you'd have an array with only the last entry in it.
right, I did that and it worked just fine. Thank you
Also, is there a way to remove duplicate hashes inside an array?
array.uniq! is usually a good way to remove duplicate things.
1

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"}]

1 Comment

Yes, I understood what was happening and fixed it by reinitializing the hash to remove the old entries.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.