Ruby Konwertuj Obiekt na Hash

Powiedzmy, że mam Gift obiekt z @name = "book" & @price = 15.95. Jaki jest najlepszy sposób na konwersję tego Hasha {name: "book", price: 15.95} w Ruby, a nie Rails (chociaż możesz też dać Rails odpowiedź)?

Author: Max, 2011-02-17

16 answers

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}

Alternatywnie z 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}
 72
Author: Vasiliy Ermolovich,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-27 21:13:35

Just say (current object) .attributes

.attributes zwraca hash dowolnego object. I jest dużo czystsza.

 268
Author: Austin Marusco,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-13 19:53:26

Zaimplementować #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
 41
Author: levinalex,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-21 02:50:11
Gift.new.instance_values # => {"name"=>"book", "price"=>15.95}
 36
Author: Erik Reedstrom,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-03-28 15:48:17

Dla Obiektów 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

A potem po prostu zadzwoń

gift.to_hash()
purch.to_hash() 
 13
Author: mcm,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-24 19:33:57
class Gift
  def to_hash
    instance_variables.map do |var|
      [var[1..-1].to_sym, instance_variable_get(var)]
    end.to_h
  end
end
 11
Author: tokland,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-31 12:59:44

Jeśli nie znajdujesz się w środowisku Rails (np. nie ma ActiveRecord ' a), może to być pomocne:

JSON.parse( object.to_json )
 9
Author: Andreas Rayo Kniep,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-25 23:47:41

Możesz użyć metody as_json. Zamieni Twój obiekt w hash.

Ale ten hash pojawi się jako wartość do nazwy tego obiektu jako klucza. W Twoim przypadku,

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

Jeśli potrzebujesz hasha, który jest przechowywany w obiekcie, użyj as_json(root: false). Myślę, że domyślnie root będzie false. Aby uzyskać więcej informacji, zapoznaj się z oficjalnym przewodnikiem po ruby

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

 8
Author: vicke4,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-27 17:10:01

Możesz napisać bardzo eleganckie rozwiązanie, używając funkcjonalnego stylu.

class Object
  def hashify
    Hash[instance_variables.map { |v| [v.to_s[1..-1].to_sym, instance_variable_get v] }]
  end
end
 6
Author: Nate Symer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-03 20:37:02

Należy nadpisać metodę inspect obiektu, aby zwrócić żądany hash, lub po prostu zaimplementować podobną metodę bez nadpisywania domyślnego zachowania obiektu.

Jeśli chcesz uzyskać więcej fantazji, możesz iterować nad zmiennymi instancji obiektu za pomocą object.instance_variables

 4
Author: Dominic,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-17 15:03:24

Rekurencyjnie Konwertuj obiekty na hash używając gem' hashable ' ( https://rubygems.org/gems/hashable ) przykład

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}}]}
 4
Author: mustafaturan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-26 19:23:42

Może warto spróbować instance_values. To mi pomogło.

 3
Author: Hunter,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-22 21:10:28

Tworzy płytką kopię jako obiekt hashowy tylko atrybutów modelu

my_hash_gift = gift.attributes.dup

Sprawdzenie typu wynikowego obiektu

my_hash_gift.class
=> Hash
 1
Author: Sean,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-18 06:20:53

Powinieneś spróbować Hashie, cudownego klejnotu : https://github.com/intridea/hashie

 0
Author: andoke,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-09-11 14:48:18

Jeśli chcesz, aby zagnieżdżone obiekty również zostały przekonwertowane.

# @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 # }}}
 0
Author: Santiago,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-28 18:23:05

Prezent.nowy.atrybuty.symbolize_keys

 0
Author: Lalit Kumar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-27 10:44:50