如何将字符串转换为对象

时间:2014-10-07 18:21:07

标签: ruby reflection polymorphism

我有以下方法来读取JSON文件并将其转换为Question对象:

def self.deserializeQuestions(json)
  if json.nil?
  else
    data = JSON.parse(json)
    questions = Hash.new
    data['questions'].map do |q|
      questions[q['id']] = Question.new(q['id'], q['questionText'])
    end
  end
end

JSON包含与不同类对应的不同类型的问题。类型为'multichoice''truefalse'等,类别为MultichoiceQuestionTrueFalseQuestion等。所有类型都来自Question,但仍有{ {1}}和id

以下是我使用的JSON文件示例:

questionText

如何修改此代码,以便能够根据属性类型创建特定类型的{ "questions": [ { "type": "multichoice", "id" : 1, "questionText": "Scala is...", "alternatives": [ { "text": "alternative 1", "code": 1, "value": 1 }, { "text": "alternative 2", "code": 2, "value": -0.25 }, { "text": "alternative 3", "code": 3, "value": -0.25 } ] }, { "type" : "truefalse", "id" : 2, "questionText": "Ruby creator is Yukihiro Matsumoto", "correct": true, "valueOK": 1, "valueFailed": -0.25, } ] }

2 个答案:

答案 0 :(得分:2)

以下是我将使用Struct -

为您的问题建模的内容
  hash = { "questions" => 
         [
           {
             "type" => "multichoice", 
             "id" => 1,
             "questionText" => "Scala is...",
           },
           {
             "type" => "truefalse",
             "id" => 2,
             "questionText" => "Ruby creator is Yukihiro Matsumoto",
           }
         ]
      }

questions = hash['questions'].map do |inner_hash| 
  Struct.new(inner_hash['type'].capitalize, :id, :question_text).new(*inner_hash.values_at('id', 'questionText'))
end

questions
# => [#<struct Struct::Multichoice id=1, question_text="Scala is...">,
#     #<struct Struct::Truefalse
#      id=2,
#      question_text="Ruby creator is Yukihiro Matsumoto">]

questions.map(&:values)
# => [[1, "Scala is..."], [2, "Ruby creator is Yukihiro Matsumoto"]]

答案 1 :(得分:1)

假设类型对应关系表示为哈希

TypeClass = {
  "multichoice" => MultichoiceQuestion,
  "truefalse" => TrueFalseQuestion,
  ...
}

然后,做:

JSON.parse(json)["questions"].each_with_object({}) do |h, questions|
  questions[h["id"]] = TypeClass[h["type"]].new(h["id"], h["questionText"])
end