Ruby 将对象转换为哈希

发布于 2024-10-18 01:20:17 字数 194 浏览 2 评论 0原文

假设我有一个 Gift 对象,其中 @name = "book" & @价格 = 15.95。将其转换为 Ruby 中的哈希 {name: "book", Price: 15.95} 的最佳方法是什么,而不是 Rails(尽管也可以随意给出 Rails 答案)?

Let's say I have a Gift object with @name = "book" & @price = 15.95. What's the best way to convert that to the Hash {name: "book", price: 15.95} in Ruby, not Rails (although feel free to give the Rails answer too)?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(20

就此别过 2024-10-25 01:20:18

只是说(当前对象).attributes

.attributes 返回任何对象哈希。而且它也干净得多。

Just say (current object) .attributes

.attributes returns a hash of any object. And it's much cleaner too.

柒七 2024-10-25 01:20:18
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}
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}

Alternatively with 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}
东京女 2024-10-25 01:20:18
Gift.new.instance_values # => {"name"=>"book", "price"=>15.95}
Gift.new.instance_values # => {"name"=>"book", "price"=>15.95}
ぽ尐不点ル 2024-10-25 01:20:18

实施#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

Implement #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
坦然微笑 2024-10-25 01:20:18

您可以使用 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

You can use as_json method. It'll convert your object into hash.

But, that hash will come as a value to the name of that object as a key. In your case,

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

If you need a hash that's stored in the object use as_json(root: false). I think by default root will be false. For more info refer official ruby guide

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

诺曦 2024-10-25 01:20:18

对于 Active Record 对象

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() 

For Active Record Objects

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

and then just call

gift.to_hash()
purch.to_hash() 
七度光 2024-10-25 01:20:18
class Gift
  def to_hash
    instance_variables.map do |var|
      [var[1..-1].to_sym, instance_variable_get(var)]
    end.to_h
  end
end
class Gift
  def to_hash
    instance_variables.map do |var|
      [var[1..-1].to_sym, instance_variable_get(var)]
    end.to_h
  end
end
无所谓啦 2024-10-25 01:20:18

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

JSON.parse( object.to_json )

If you are not in an Rails environment (ie. don't have ActiveRecord available), this may be helpful:

JSON.parse( object.to_json )
溺孤伤于心 2024-10-25 01:20:18

您可以使用函数式风格编写非常优雅的解决方案。

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

You can write a very elegant solution using a functional style.

class Object
  def hashify
    Hash[instance_variables.map { |v| [v.to_s[1..-1].to_sym, instance_variable_get v] }]
  end
end
贩梦商人 2024-10-25 01:20:18

使用“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}}]}

Recursively convert your objects to hash using 'hashable' gem (https://rubygems.org/gems/hashable)
Example

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}}]}
智商已欠费 2024-10-25 01:20:18

您应该重写对象的 inspect 方法以返回所需的哈希值,或者仅实现类似的方法而不重写默认的对象行为。

如果您想要更高级,可以使用 object.instance_variables

You should override the inspect method of your object to return the desired hash, or just implement a similar method without overriding the default object behaviour.

If you want to get fancier, you can iterate over an object's instance variables with object.instance_variables

喜爱纠缠 2024-10-25 01:20:18

可能想尝试instance_values。这对我有用。

Might want to try instance_values. That worked for me.

夜空下最亮的亮点 2024-10-25 01:20:18

抄袭@Mr. L 在上面的评论中,尝试 @gift.attributes.to_options

To plagiarize @Mr. L in a comment above, try @gift.attributes.to_options.

扭转时空 2024-10-25 01:20:18

您可以使用symbolize_keys,如果您有嵌套属性,我们可以使用deep_symbolize_keys

gift.as_json.symbolize_keys => {name: "book", price: 15.95}
 

You can use symbolize_keys and in-case you have nested attributes we can use deep_symbolize_keys:

gift.as_json.symbolize_keys => {name: "book", price: 15.95}
 
眼中杀气 2024-10-25 01:20:18

生成浅表副本作为模型属性的哈希对象

my_hash_gift = gift.attributes.dup

检查结果对象的类型

my_hash_gift.class
=> Hash

Produces a shallow copy as a hash object of just the model attributes

my_hash_gift = gift.attributes.dup

Check the type of the resulting object

my_hash_gift.class
=> Hash
天涯沦落人 2024-10-25 01:20:18

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

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

If you need nested objects to be converted as well.

# @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 # }}}
花之痕靓丽 2024-10-25 01:20:18

Gift.new.attributes.symbolize_keys

Gift.new.attributes.symbolize_keys

墨离汐 2024-10-25 01:20:18

要在不使用 Rails 的情况下执行此操作,一种简洁的方法是将属性存储在常量中。

class Gift
  ATTRIBUTES = [:name, :price]
  attr_accessor(*ATTRIBUTES)
end

然后,要将 Gift 实例转换为 Hash,您可以:

class Gift
  ...
  def to_h
    ATTRIBUTES.each_with_object({}) do |attribute_name, memo|
      memo[attribute_name] = send(attribute_name)
    end
  end
end

这是一个很好的方法,因为它只包含您在 上定义的内容attr_accessor,而不是每个实例变量。

class Gift
  ATTRIBUTES = [:name, :price]
  attr_accessor(*ATTRIBUTES)

  def create_random_instance_variable
    @xyz = 123
  end

  def to_h
    ATTRIBUTES.each_with_object({}) do |attribute_name, memo|
      memo[attribute_name] = send(attribute_name)
    end
  end
end

g = Gift.new
g.name = "Foo"
g.price = 5.25
g.to_h
#=> {:name=>"Foo", :price=>5.25}

g.create_random_instance_variable
g.to_h
#=> {:name=>"Foo", :price=>5.25}

To do this without Rails, a clean way is to store attributes on a constant.

class Gift
  ATTRIBUTES = [:name, :price]
  attr_accessor(*ATTRIBUTES)
end

And then, to convert an instance of Gift to a Hash, you can:

class Gift
  ...
  def to_h
    ATTRIBUTES.each_with_object({}) do |attribute_name, memo|
      memo[attribute_name] = send(attribute_name)
    end
  end
end

This is a good way to do this because it will only include what you define on attr_accessor, and not every instance variable.

class Gift
  ATTRIBUTES = [:name, :price]
  attr_accessor(*ATTRIBUTES)

  def create_random_instance_variable
    @xyz = 123
  end

  def to_h
    ATTRIBUTES.each_with_object({}) do |attribute_name, memo|
      memo[attribute_name] = send(attribute_name)
    end
  end
end

g = Gift.new
g.name = "Foo"
g.price = 5.25
g.to_h
#=> {:name=>"Foo", :price=>5.25}

g.create_random_instance_variable
g.to_h
#=> {:name=>"Foo", :price=>5.25}
川水往事 2024-10-25 01:20:18

我开始使用结构来轻松进行哈希转换。
我没有使用裸结构,而是创建了自己的从哈希派生的类,这允许您创建自己的函数,并且它记录了类的属性。

require 'ostruct'

BaseGift = Struct.new(:name, :price)
class Gift < BaseGift
  def initialize(name, price)
    super(name, price)
  end
  # ... more user defined methods here.
end

g = Gift.new('pearls', 20)
g.to_h # returns: {:name=>"pearls", :price=>20}

I started using structs to make easy to hash conversions.
Instead of using a bare struct I create my own class deriving from a hash this allows you to create your own functions and it documents the properties of a class.

require 'ostruct'

BaseGift = Struct.new(:name, :price)
class Gift < BaseGift
  def initialize(name, price)
    super(name, price)
  end
  # ... more user defined methods here.
end

g = Gift.new('pearls', 20)
g.to_h # returns: {:name=>"pearls", :price=>20}
樱花落人离去 2024-10-25 01:20:18

按照我无法编译的 Nate 答案:

选项 1

class Object
    def to_hash
        instance_variables.map{ |v| Hash[v.to_s.delete("@").to_sym, instance_variable_get(v)] }.inject(:merge)
   end
end

然后你这样称呼它:

my_object.to_hash[:my_variable_name]

选项 2

class Object
    def to_hash
        instance_variables.map{ |v| Hash[v.to_s.delete("@"), instance_variable_get(v)] }.inject(:merge)
   end
end

然后你这样称呼它:

my_object.to_hash["my_variable_name"]

Following Nate's answer which I haven't been able to compile:

Option 1

class Object
    def to_hash
        instance_variables.map{ |v| Hash[v.to_s.delete("@").to_sym, instance_variable_get(v)] }.inject(:merge)
   end
end

And then you call it like that:

my_object.to_hash[:my_variable_name]

Option 2

class Object
    def to_hash
        instance_variables.map{ |v| Hash[v.to_s.delete("@"), instance_variable_get(v)] }.inject(:merge)
   end
end

And then you call it like that:

my_object.to_hash["my_variable_name"]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文