Extract hash in Ruby on Rails

1

I have the following Hash

my_hash = {city: {id:1, created_at: '', name: 'test_city'}, 
           uf: {id:1, created_at: '', name: 'test_uf'}}

I need to extract some data from it eg:

my_hash.extract!({city: [:id, :name], uf: [:id, :name]})

Expected return:

{city: {id:1, name: 'test_city'}, uf: {id:1, name: 'test_uf'}}

Why does not it work, what is the best way to do this?

    
asked by anonymous 29.04.2015 / 14:02

1 answer

0

There is an extension in 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 method of class 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 in the way you suggested.

    
01.05.2015 / 07:39