Ruby конвертирует Object в Hash - PullRequest
       22

Ruby конвертирует Object в Hash

113 голосов
/ 17 февраля 2011

Допустим, у меня есть Gift объект с @name = "book" & @price = 15.95. Какой лучший способ преобразовать это в Hash {name: "book", price: 15.95} в Ruby, а не в Rails (хотя не стесняйтесь давать ответ и Rails)?

Ответы [ 17 ]

279 голосов
/ 03 ноября 2012

Просто скажите (текущий объект) .attributes

.attributes возвращает hash любого object.И это намного чище.

77 голосов
/ 17 февраля 2011
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}
46 голосов
/ 17 февраля 2011

Реализация #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
40 голосов
/ 28 марта 2012
Gift.new.instance_values # => {"name"=>"book", "price"=>15.95}
13 голосов
/ 24 июня 2011

Для объектов активной записи

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() 
12 голосов
/ 27 января 2017

Вы можете использовать as_json метод. Это преобразует ваш объект в хеш.

Но этот хеш придет в качестве значения имени этого объекта в качестве ключа. В вашем случае

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

Если вам нужен хеш, который хранится в объекте, используйте as_json(root: false). Я думаю, что по умолчанию root будет ложным. Для получения дополнительной информации обратитесь к официальному гиду по рубину

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

11 голосов
/ 17 февраля 2011
class Gift
  def to_hash
    instance_variables.map do |var|
      [var[1..-1].to_sym, instance_variable_get(var)]
    end.to_h
  end
end
9 голосов
/ 26 сентября 2014

Если вы не находитесь в среде Rails (т. Е. У вас нет ActiveRecord), это может быть полезно:

JSON.parse( object.to_json )
6 голосов
/ 14 апреля 2014

Вы можете написать очень элегантное решение, используя функциональный стиль.

class Object
  def hashify
    Hash[instance_variables.map { |v| [v.to_s[1..-1].to_sym, instance_variable_get v] }]
  end
end
4 голосов
/ 26 июля 2013

Рекурсивно конвертируйте ваши объекты в хэш, используя гем '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}}]}
...