将哈希映射映射到类实例

时间:2012-08-13 12:43:30

标签: ruby-on-rails ruby gem

寻找宝石或者至少知道如何解决这个问题,我所拥有的并不完全优雅:)

想法很简单我想映射哈希,例如:

{ :name => 'foo',
  :age  => 15,
  :job => {
        :job_name => 'bar',
        :position => 'something'
    ...
  }
}

对象的对象(具有平面成员结构)或结构,例如:

class Person {
  @name
  @age
  @job_name
  ...
}

谢谢大家。

3 个答案:

答案 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"