slayedbylucifer
slayedbylucifer

Reputation: 23532

Merge two hashes on a particular value

I am checking whether the hash hash_volumes below has a key whose instance_id matches with a key of hash hash_instance.

hash_volumes = {
  :"vol-d16d12b8" => {
        :instance_id => "i-4e4ba679",
    },
}
hash_instance = {
  :"i-4e4ba679" => {
        :arch => "x86_64",
    },
}

If it does, then I need to merge it to the hash_instance. I find that vol-d16d12b8 matches with the instance i-4e4ba679 and hence I want to merge it with hash_instance so that the final hash_instance will look like below:

hash_instance = {
  :"i-4e4ba679" => {
        :arch => "x86_64",
        :volume => "vol-d16d12b8"  # this is new entry to `hash_instance`
    },
}

I am not able to merge these two hashes as explained above. I suspect my if statement is wrong. Please take a look at my code below:

hash_volumes.each_key do |x|
  hash_instance.each_key do |y|
    if hash_volumes[x][:instance_id] == y  ## I think this line is the problem
      hash_instance[y][:volume] = x
    end
  end
end

hash_instance

Output:

{
    :"i-4e4ba679" => {
        :arch => "x86_64"
    }
}

The code above gives hash_instance without adding volume to it. I tried as below, but none worked:

if hash_volumes[x][:instance_id] == "#{y}"
# => this if statement gives me syntax error

.....

if hash_volumes[x][:instance_id] =~ /"#{y}"/
# => this if statement does not make any changes to above output.

Upvotes: 1

Views: 78

Answers (2)

7stud
7stud

Reputation: 48659

hash_volumes = {
  :"vol-d16d12b8" => {
        :instance_id => "i-4e4ba679",
    },
}

hash_instance = {
  :"i-4e4ba679" => {
        :arch => "x86_64",
    },
}

hash_volumes.each do |key, val|
  id = val[:instance_id]  #returns nil if the there is no :instance_id key

  if id 
    id_as_sym = id.to_sym

    if hash_instance.has_key? id_as_sym
      hash_instance[id_as_sym][:volume] = id
    end
  end
end


--output:--
{:"i-4e4ba679"=>{:arch=>"x86_64", :volume=>"i-4e4ba679"}}

Upvotes: 3

sawa
sawa

Reputation: 168269

A simple implementation would be this:

hash_instance.each do |k1, v1|
  next unless k = hash_volumes.find{|k2, v2| v2[:instance_id].to_sym == k1}
  v1[:volume] = k.first
end

Upvotes: 1

Related Questions