&を持つGift
オブジェクトがある@name = "book"
とし@price = 15.95
ます。これを{name: "book", price: 15.95}
RailsではなくRuby のハッシュに変換する最良の方法は何ですか(ただし、Railsにも回答を提供してください)。
&を持つGift
オブジェクトがある@name = "book"
とし@price = 15.95
ます。これを{name: "book", price: 15.95}
RailsではなくRuby のハッシュに変換する最良の方法は何ですか(ただし、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}
var.to_s.delete("@")
てvar[1..-1].to_sym
シンボルを取得します。
gift.instance_variables.each_with_object({}) { |var,hash| hash[var.to_s.delete("@")] = gift.instance_variable_get(var) }
して、末尾を; hash
each
。map
そして、inject
はるかに強力です。これは、Rubyで私が持っている1つの設計品質で map
ありinject
、で実装されていeach
ます。それは単に悪いコンピュータサイエンスです。
hash = Hash[gift.instance_variables.map { |var| [var.to_s[1..-1], gift.instance_variable_get(var)] } ]
(現在のオブジェクト)と言うだけです .attributes
.attributes
hash
任意のを返しますobject
。そして、それもはるかにきれいです。
.values
:sequel.jeremyevans.net/rdoc/classes/Sequel/Model/...
instance_values
同様の出力のすべてのルビーオブジェクトに使用できます。
実装し#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
Use :: for describing class methods, # for describing instance methods, and use . for example code
ソース:ruby-doc.org/documentation-guidelines.html)また、公式ドキュメント(ruby CHANGELOG、github.com / ruby / ruby / blob / v2_1_0 / NEWSなど)は#
インスタンスメソッドとドットを使用しますクラスメソッドの場合はかなり一貫しています。
each_with_object
:instance_variables.each_with_object(Hash.new(0)) { |element, hash| hash["#{element}".delete("@").to_sym] = instance_variable_get(element) }
Gift.new.instance_values # => {"name"=>"book", "price"=>15.95}
instance_values
。MattがRubyの方法を要求したことに注意してください。具体的にはRailsではありません。
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
アクティブレコードオブジェクトの場合
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()
Rails環境でない場合(つまり、ActiveRecordを使用できない場合)、これが役立つことがあります。
JSON.parse( object.to_json )
inspect
オブジェクトのメソッドをオーバーライドして目的のハッシュを返すか、デフォルトのオブジェクトの動作をオーバーライドせずに同様のメソッドを実装する必要があります。
より洗練されたものにしたい場合は、object.instance_variablesを使用してオブジェクトのインスタンス変数を反復できます。
'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}}]}
ネストされたオブジェクトも変換する必要がある場合。
# @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 # }}}
Gift.new.attributes.symbolize_keys
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}
ハッシュ変換を簡単にするために構造体を使い始めました。裸の構造体を使用する代わりに、ハッシュから派生した独自のクラスを作成します。これにより、独自の関数を作成でき、クラスのプロパティをドキュメント化します。
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}