3

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

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

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

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

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

谢谢大家。

4

3 回答 3

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
于 2012-08-13T13:46:02.963 回答
0

我使用它的解决方案解决了具有相同键名的问题,但它没有提供扁平的类结构。有人可能会觉得这很方便,请记住需要处理具有保留名称(例如idtype )的值。

   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
于 2012-08-13T13:55:14.617 回答
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"
于 2012-08-13T13:56:49.063 回答