寻找宝石或者至少知道如何解决这个问题,我所拥有的并不完全优雅:)
想法很简单我想映射哈希,例如:
{ :name => 'foo',
:age => 15,
:job => {
:job_name => 'bar',
:position => 'something'
...
}
}
对象的对象(具有平面成员结构)或结构,例如:
class Person {
@name
@age
@job_name
...
}
谢谢大家。
答案 0 :(得分:1)
假设您可以确定子条目密钥不会与包含条目密钥冲突,这里有一些应该有效的代码......
require 'ostruct'
def flatten_hash(hash)
hash = hash.dup
hash.entries.each do |k,v|
next unless v.is_a?(Hash)
v = flatten_hash(v)
hash.delete(k)
hash.merge! v
end
hash
end
def flat_struct_from_hash(hash)
hash = flatten_hash(hash)
OpenStruct.new(hash)
end
答案 1 :(得分:0)
我使用它的解决方案解决了相同键名的问题,但它没有给出平面类结构。有人可能会发现这个方便,请记住,需要处理具有保留名称的值,例如 id , type 。
require 'ostruct'
def to_open_struct(element)
struct = OpenStruct.new
element.each do |k,v|
value = Hash === v ? to_open_struct(v) : v
eval("object.#{k}=value")
end
return struct
end
答案 2 :(得分:0)
另一个答案,你知道前面的键
class Job
attr_accessor :job_name, :position
def initialize(params = {})
self.job_name = params.fetch(:job_name, nil)
self.position = params.fetch(:position, nil)
end
end
class Person
attr_accessor :name, :age, :job
def initialize(params = {})
self.name = params.fetch(:name, nil)
self.age = params.fetch(:age, nil)
self.job = Job.new(params.fetch(:job, {}))
end
end
hash = { :name => 'foo', :age => 1, :job => { :job_name => 'bar', :position => 'soetmhing' }}
p = Person.new(hash)
p.name
==> "foo"
p.job
==> #<Job:0x96cacd8 @job_name="bar", @position="soetmhing">
p.job.name
==> "bar"