There is an extension on ActiveSupport
that allows you to extract keys from a Hash
:
my_hash = {
city: {
id: 1,
created_at: '',
name: 'test_city'
},
uf: {
id: 1,
created_at: '',
name: 'test_uf'
}
}
my_hash[:city].slice(:id, :name) #=> { id: 1, name: 'test_city' }
It’s not quite the behavior you want, but it can be used to solve your problem as follows:
Hash[my_hash.slice(:city, :uf). { |k, v| [k, v.slice(:id, :name) }]
This behavior could be generalized and encapsulated in a class method Hash
as follows - as available in makandra cards:
Hash.class_eval do
def deep_slice(*allowed_keys)
sliced = {}
allowed_keys.each do |allowed_key|
if allowed_key.is_a?(Hash)
allowed_key.each do |allowed_subkey, allowed_subkey_values|
if has_key?(allowed_subkey)
value = self[allowed_subkey]
if value.is_a?(Hash)
sliced[allowed_subkey] = value.deep_slice(*Array.wrap(allowed_subkey_values))
else
raise ArgumentError, "can only deep-slice hash values, but value for #{allowed_subkey.inspect} was of type #{value.class.name}"
end
end
end
else
if has_key?(allowed_key)
sliced[allowed_key] = self[allowed_key]
end
end
end
sliced
end
end
So this method could be used the way you suggested.
Extract will modify the original hash and return you another hash, that’s what you want to do, or you just want to access the values?
– Alex Takitani
What do you expect in return? Give an example.
– Juliano Alves
I edited the question with the expected values.
– Daniel