logo ruby object hashmap instance-variables

logo - Ruby convert Object a hash



hbase (16)

Convierta recursivamente sus objetos en hash usando la gema ''hashable'' ( https://rubygems.org/gems/hashable )

class A include Hashable attr_accessor :blist def initialize @blist = [ B.new(1), { ''b'' => B.new(2) } ] end end class B include Hashable attr_accessor :id def initialize(id); @id = id; end end a = A.new a.to_dh # or a.to_deep_hash # {:blist=>[{:id=>1}, {"b"=>{:id=>2}}]}

Digamos que tengo un objeto de Gift con @name = "book" y @price = 15.95 . ¿Cuál es la mejor manera de convertir eso a Hash {name: "book", price: 15.95} en Ruby, no Rails (aunque no dude en dar la respuesta de Rails también)?


Debe anular el método de inspect de su objeto para devolver el hash deseado o simplemente implementar un método similar sin anular el comportamiento predeterminado del objeto.

Si quieres ser más elegante, puedes iterar sobre las variables de instancia de un objeto con object.instance_variables



Es posible que desee probar instance_values . Eso funcionó para mí.


Gift.new.attributes.symbolize_keys


Implementar #to_hash ?

class Gift def to_hash hash = {} instance_variables.each {|var| hash[var.to_s.delete("@")] = instance_variable_get(var) } hash end end h = Gift.new("Book", 19).to_hash


Para objetos de registro activo

module ActiveRecordExtension def to_hash hash = {}; self.attributes.each { |k,v| hash[k] = v } return hash end end class Gift < ActiveRecord::Base include ActiveRecordExtension .... end class Purchase < ActiveRecord::Base include ActiveRecordExtension .... end

y luego solo llama

gift.to_hash() purch.to_hash()


Produce una copia superficial como un objeto hash de solo los atributos del modelo

my_hash_gift = gift.attributes.dup

Verifica el tipo del objeto resultante

my_hash_gift.class => Hash


Puede escribir una solución muy elegante usando un estilo funcional.

class Object def hashify Hash[instance_variables.map { |v| [v.to_s[1..-1].to_sym, instance_variable_get v] }] end end


Puedes usar el método as_json . Convertirá tu objeto en hash.

Pero, ese hash vendrá como un valor para el nombre de ese objeto como una clave. En tu caso,

{''gift'' => {''name'' => ''book'', ''price'' => 15.95 }}

Si necesita un hash almacenado en el objeto, use as_json(root: false) . Creo que por defecto root será falso. Para obtener más información, consulte la guía oficial de rubí

http://api.rubyonrails.org/classes/ActiveModel/Serializers/JSON.html#method-i-as_json


Si necesita convertir objetos anidados también.

# @fn to_hash obj {{{ # @brief Convert object to hash # # @return [Hash] Hash representing converted object # def to_hash obj Hash[obj.instance_variables.map { |key| variable = obj.instance_variable_get key [key.to_s[1..-1].to_sym, if variable.respond_to? <:some_method> then hashify variable else variable end ] }] end # }}}


Si no está en un entorno Rails (es decir, no tiene ActiveRecord disponible), esto puede ser útil:

JSON.parse( object.to_json )


Solo diga (objeto actual). .attributes

.attributes devuelve un hash de cualquier object . Y es mucho más limpio también.


Gift.new.instance_values # => {"name"=>"book", "price"=>15.95}


class Gift def initialize @name = "book" @price = 15.95 end end gift = Gift.new hash = {} gift.instance_variables.each {|var| hash[var.to_s.delete("@")] = gift.instance_variable_get(var) } p hash # => {"name"=>"book", "price"=>15.95}

Alternativamente con each_with_object :

gift = Gift.new hash = gift.instance_variables.each_with_object({}) { |var, hash| hash[var.to_s.delete("@")] = gift.instance_variable_get(var) } p hash # => {"name"=>"book", "price"=>15.95}


class Gift def to_hash instance_variables.map do |var| [var[1..-1].to_sym, instance_variable_get(var)] end.to_h end end