Ruby将对象转换为散列

假设我有@name = "book"@price = 15.95Gift对象。 什么是最好的方式转换为哈希{name: "book", price: 15.95}在Ruby中,而不是Rails(尽pipe也可以给Rails的答案)?

 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} 

或者使用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} 

只要说(当前对象) .attributes

.attributes返回任何objecthash 。 而且它也更干净。

实施#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 
 Gift.new.instance_values # => {"name"=>"book", "price"=>15.95} 

对于活动logging对象

 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 

然后就打电话

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

如果你不在Rails环境下(即没有ActiveRecord可用),这可能会有帮助:

 JSON.parse( object.to_json ) 

您可以使用function风格编写一个非常优雅的解决scheme。

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

您应该重写对象的inspect方法以返回所需的散列,或者只是实现一个类似的方法,而不会覆盖默认的对象行为。

如果你想更有趣 ,你可以使用object.instance_variables迭代对象的实例variables

使用“hashable”gem( https://rubygems.org/gems/hashable )将对象recursion转换为哈希

 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}}]} 

你可以使用as_json方法。 它会把你的对象转换成哈希。

但是,这个哈希将作为一个关键的对象的名称价值。 在你的情况下,

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

如果您需要存储在对象中的散列,请使用as_json(root: false) 。 我认为默认情况下root会是false。 欲了解更多信息,请参阅官方ruby指南

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

可能要尝试instance_values 。 这对我有效。

生成浅拷贝作为模型属性的散列对象

 my_hash_gift = gift.attributes.dup 

检查结果对象的types

 my_hash_gift.class => Hash 

你应该尝试Hashie,一个奇妙的gem: https : //github.com/intridea/hashie

如果您还需要转换嵌套的对象。

 # @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 # }}}