Ruby将Object转换为Hash

ma1*_*w28 122 ruby object hashmap instance-variables

假设我有&的Gift对象.将它转换为Ruby中的Hash的最佳方法是什么,而不是Rails(尽管也可以自由地给出Rails的答案)?@name = "book"@price = 15.95{name: "book", price: 15.95}

小智 286

只说(当前对象) .attributes

.attributes返回hash任何一个object.而且它也更清洁.

  • 请注意,这是一个特定于ActiveModel的方法,而不是Ruby方法. (134认同)
  • 在续集的情况下 - 使用`.values`:http://sequel.jeremyevans.net/rdoc/classes/Sequel/Model/InstanceMethods.html (6认同)
  • `instance_values` 可用于类似输出的所有 ruby​​ 对象。 (2认同)

Vas*_*ich 79

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}
Run Code Online (Sandbox Code Playgroud)

或者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}
Run Code Online (Sandbox Code Playgroud)

  • 尼斯.我用`var [1 ..- 1] .to_sym`替换`var.to_s.delete("@")`来获取符号. (8认同)
  • 您可以使用inject跳过初始化变量:gift.instance_variables.inject({}){| hash,var | hash [var.to_s.delete("@")] = gift.instance_variable_get(var); 哈希} (3认同)
  • 不要使用inject,请使用`gift.instance_variables.each_with_object({}){| var,hash | hash [var.to_s.delete("@")] = gift.instance_variable_get(var)}`并摆脱尾随的; hash` (3认同)
  • 我永远不会理解“每个”对红宝石的迷恋。`map` 和 `inject` 更强大。这是我对 Ruby 的一个设计疑虑:`map` 和 `inject` 是用 `each` 实现的。这简直是​​糟糕的计算机科学。 (2认同)

lev*_*lex 47

实施#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
Run Code Online (Sandbox Code Playgroud)

  • 实际上,没有.RDoc文档说:"使用::描述类方法,#用于描述实例方法,并使用.例如代码`(来源:http://ruby-doc.org/documentation-guidelines.html)另外,官方文档(如红宝石CHANGELOG,https://github.com/ruby/ruby/blob/v2_1_0/NEWS )使用`#`作为实例方法,使用类方法的点非常一致. (6认同)

Eri*_*rom 40

Gift.new.instance_values # => {"name"=>"book", "price"=>15.95}
Run Code Online (Sandbox Code Playgroud)

  • 他还说也可以自由地给出Rails答案......所以我做到了. (26认同)
  • 这是Rails,Ruby本身没有`instance_values`.请注意,Matt要求使用Ruby方式,特别是Rails. (10认同)

vic*_*ke4 16

你可以使用as_json方法.它会将您的对象转换为哈希值.

但是,该哈希值将作为该对象名称的值作为键.在你的情况下,

{'gift' => {'name' => 'book', 'price' => 15.95 }}
Run Code Online (Sandbox Code Playgroud)

如果需要存储在对象中的哈希值as_json(root: false).我认为默认情况下root将是false.有关更多信息,请参阅官方红宝石指南

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


mon*_*amp 13

对于活动记录对象

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
Run Code Online (Sandbox Code Playgroud)

然后打电话

gift.to_hash()
purch.to_hash() 
Run Code Online (Sandbox Code Playgroud)

  • 好笑,它不是Rails框架的一部分.看起来像是有用的东西. (2认同)

tok*_*and 11

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


And*_*iep 10

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

JSON.parse( object.to_json )
Run Code Online (Sandbox Code Playgroud)


Nat*_*mer 6

您可以使用功能样式编写非常优雅的解决方案.

class Object
  def hashify
    Hash[instance_variables.map { |v| [v.to_s[1..-1].to_sym, instance_variable_get v] }]
  end
end
Run Code Online (Sandbox Code Playgroud)


mus*_*ran 5

使用 'hashable' gem ( 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}}]}
Run Code Online (Sandbox Code Playgroud)