2012-10-04 32 views
16

Tôi nhìn vào các nguồn tài nguyên khác nhau và vẫn bị lẫn lộn về cách phân tích một định dạng json đến một đối tượng tùy chỉnh, ví dụparse json phản đối ruby ​​

class Resident 
    attr_accessor :phone, :addr 

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

và tệp JSON

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

gì là cách chính xác để phân tích các tập tin json thành một mảng của 3 đối tượng cư trú?

+2

Phân tích cú pháp JSON này thành băm ruby, sau đó đi bộ băm đó và tạo đối tượng Cư trú. –

+0

@SergioTulentsev là sử dụng JSON.parse (jsonfile)? –

+0

flint_stone: Vâng, chính xác. –

Trả lời

26

Các mã sau là đơn giản hơn:

require 'json' 

data = JSON.parse(json_data) 
residents = data['Resident'].map { |rd| Resident.new(rd['phone'], rd['addr']) } 
4
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" 
+0

Đó không phải là xấu, nhưng bạn có thể sử dụng 'Enumerable # map' thay vì mỗi. –

+0

'inject' thậm chí còn tốt hơn :) –

+0

Tôi đã thêm ý tưởng của mình làm câu trả lời. –

36

Hôm nay tôi đang tìm kiếm một cái gì đó có thể chuyển đổi json đến một đối tượng, và điều này hoạt động giống như một nét duyên dáng:

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

Bằng cách này bạn có thể làm person.education.school hoặc person[0].education.school nếu phản hồi là một mảng

Tôi để nó ở đây vì có thể hữu ích cho ai đó

+4

imho cách tốt nhất để làm điều đó. – Alu

+1

Thuận tiện, nhưng không phải là đối tượng tùy chỉnh. –

2

Gần đây, chúng tôi đã phát hành một thư viện Ruby static_struct giải quyết vấn đề. Check it out.

0

Nếu bạn đang sử dụng ActiveModel::Serializers::JSON bạn chỉ có thể gọi from_json(json) và đối tượng của bạn sẽ được ánh xạ với các giá trị đó.

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 
Các vấn đề liên quan