0
votes

I would like to find an efficient way to merge two hashes together and the resulting hash must contain all original data and a new key/value pair based on criteria below. There are no keys in common between the two hashes, however the key in one hash matches the value of a key in the adjacent hash.

Also note that the second hash is actually an array of hashes.

I am working with a relatively large data set, so looking for an efficient solution but hoping to keep the code readable at the same time since it will likely end up in production.

Here is the structure of my data:

# Hash
hsh1 = { "devicename1"=>"active", "devicename2"=>"passive", "devicename3"=>"passive" }

# Array of Hashes
hsh2 = [ { "host" => "devicename3", "secure" => true  },
         { "host" => "devicename2", "secure" => true  },
         { "host" => "devicename1", "secure" => false } ]

Here is what I need to accomplish:

I need to merge the data from hsh1 into hsh2 keeping all of the original key/value pairs in hsh2 and adding a new key called activation_status using the the data in hsh1.

The resulting hsh2 would be as follows:

hsh2 = [{ "host"=>"devicename3", "secure"=>true,  "activation_status"=>"passive" },
        { "host"=>"devicename2", "secure"=>true,  "activation_status"=>"passive" },
        { "host"=>"devicename1", "secure"=>false, "activation_status"=>"active"  }]

This may already be answered on StackOverflow but I looked for some time and couldn't find a match. My apologies in advance if this is a duplicate.

2
What do you mean by "large"? Just roughly. 1000? 1000000? 1000000000?Raffael
Good question, I thought about qualifying it. In Ruby terms, I'll bet it's not that big. Just shy of 10,000.Kurt W
OK, then it should not be a problem to keep it all in the memory at once.Raffael
I hope you don't mind me editing your question. I simply reformatted to avoid the need for readers to scroll horizontally.Cary Swoveland
Thanks Cary--not at all :)Kurt W

2 Answers

3
votes

I suggest something along the lines of:

hash3 = hash2.map do |nestling|
  host = nestling["host"]
  status = hash1[host]
  nestling["activation_status"] = status
  nestling
end

Which of course you can shrink down a bit. This version uses less variables and in-place edit of hash2:

hash2.each do |nestling|
  nestling["activation_status"] = hash1[nestling["host"]]
end
1
votes

This will do it:

hsh2.map { |h| h.merge 'activation_status' => hsh1[h['host']] }

However, I think it will make a copy of the data instead of just walking the array of hashes and adding the appropriate key=>value pair. I don't think it would have a huge impact on performance unless your data set is large enough to consume a significant portion of the memory allocated to your app.