【问题标题】:parse json to object ruby将 json 解析为对象 ruby
【发布时间】:2012-09-25 05:49:47
【问题描述】:

我查看了不同的资源,但仍然对如何将 json 格式解析为自定义对象感到困惑,例如

class Resident
  attr_accessor :phone, :addr

  def initialize(phone, addr)
      @phone = phone
      @addr = addr
  end
end    

和 JSON 文件

{
  "Resident": [
    {
      "phone": "12345",
      "addr":  "xxxxx"
    }, {
      "phone": "12345",
      "addr": "xxxxx"
    }, {
      "phone": "12345",
      "addr": "xxxxx"
    }
  ]
}

将 json 文件解析为包含 3 个 Resident 对象的数组的正确方法是什么?

【问题讨论】:

  • 将此 JSON 解析为 ruby​​ 哈希,然后遍历该哈希并创建 Resident 对象。
  • @SergioTulentsev 是使用 JSON.parse(jsonfile) 吗?
  • @SergioTulentsev 谢谢我得到了那部分但是如何适应新对象?是使用 class_variable_defined 还是别的什么?
  • 只是说明需要去掉 "xxxxx" 后面的逗号,否则 JSON 会报错。

标签: ruby json


【解决方案1】:

如果您使用的是ActiveModel::Serializers::JSON,您只需调用from_json(json),您的对象就会映射到这些值。

class Person
  include ActiveModel::Serializers::JSON

  attr_accessor :name, :age, :awesome

  def attributes=(hash)
    hash.each do |key, value|
      send("#{key}=", value)
    end
  end

  def attributes
    instance_values
  end
end

json = {name: 'bob', age: 22, awesome: true}.to_json
person = Person.new
person.from_json(json) # => #<Person:0x007fec5e7a0088 @age=22, @awesome=true, @name="bob">
person.name # => "bob"
person.age # => 22
person.awesome # => true

【讨论】:

    【解决方案2】:

    我们最近发布了一个 Ruby 库 static_struct 来解决这个问题。 Check it out.

    【讨论】:

      【解决方案3】:

      今天我正在寻找将 json 转换为对象的东西,这就像一个魅力:

      person = JSON.parse(json_string, object_class: OpenStruct)
      

      如果响应是一个数组,你可以这样做person.education.schoolperson[0].education.school

      我把它留在这里是因为它可能对某人有用

      【讨论】:

      • 恕我直言,这是最好的方法。
      • 方便,但不是自定义对象。
      • 满足我的需求。谢谢!
      【解决方案4】:

      下面的代码比较简单:

      require 'json'
      
      data = JSON.parse(json_data)
      residents = data['Resident'].map { |rd| Resident.new(rd['phone'], rd['addr']) }
      

      【讨论】:

        【解决方案5】:
        require 'json'
        
        class Resident
            attr_accessor :phone, :addr
        
            def initialize(phone, addr)
                @phone = phone
                @addr = addr
            end
        end
        
        s = '{"Resident":[{"phone":"12345","addr":"xxxxx"},{"phone":"12345","addr":"xxxxx"},{"phone":"12345","addr":"xxxxx"}]}'
        
        j = JSON.parse(s)
        
        objects = j['Resident'].inject([]) { |o,d| o << Resident.new( d['phone'], d['addr'] ) }
        
        p objects[0].phone
        "12345"
        

        【讨论】:

        • 这还不错,但您可以使用Enumerable#map 代替每个。
        • 我添加了我的想法作为答案。
        猜你喜欢
        • 2011-11-30
        • 2020-10-29
        • 2020-10-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多