2015-09-13 7 views
6

मैं एक JSON प्रतिक्रिया जो हैश की एक सरणी है:JSON पार्सिंग के लिए डेटा प्रकार कैसे निर्दिष्ट करें?

[{"project" => {"id" => 1, "name" => "Internal"}, 
{"project" => {"id" => 2, "name" => "External"}}] 

मेरे कोड इस तरह दिखता है:

client = HTTP::Client.new(url, ssl: true) 
response = client.get("/projects", ssl: true) 
projects = JSON.parse(response.body) as Array 

यह मैं किसी सरणी देता है, लेकिन ऐसा लगता है मैं तत्वों को टाइपकास्ट करने की जरूरत है वास्तव में उनका उपयोग करें अन्यथा मुझे undefined method '[]' for Nil (compile-time type is (Nil | String | Int64 | Float64 | Bool | Hash(String, JSON::Type) | Array(JSON::Type))) मिलता है।

मैंने as Array(Hash) की कोशिश की लेकिन यह मुझे can't use Hash(K, V) as generic type argument yet, use a more specific type देता है।

मैं इस प्रकार को कैसे निर्दिष्ट करूं?

उत्तर

8

आप के रूप में आप तत्वों का उपयोग इन कास्ट करने के लिए है:

projects = JSON.parse(json).as(Array) 
project = projects.first.as(Hash)["project"].as(Hash) 
id = project["id"].as(Int64) 

http://carc.in/#/r/f3f

लेकिन इस तरह अच्छी तरह से संरचित डेटा के लिए आप JSON.mapping उपयोग करने के साथ बेहतर कर रहे हैं:

class ProjectContainer 
    JSON.mapping({ 
    project: Project 
    }) 
end 

class Project 
    JSON.mapping({ 
    id: Int64, 
    name: String 
    }) 
end 

projects = Array(ProjectContainer).from_json(json) 
project = projects.first.project 
pp id = project.id 

http://carc.in/#/r/f3g

आप https://github.com/manastech/crystal/issues/982#issuecomment-121156428

+1

आपने मुझे 1 मिनट के लिए हराया! – asterite

+0

प्रकट होता है #as वाक्यविन्यास बदल गया है? https://play.crystal-lang.org/#/r/1uhw या आप to_i और to_s FWIW का उपयोग कर सकते हैं। – rogerdpack

+0

सच है, मैंने जवाब अपडेट किया। –

3

पर इस समस्या का एक थोड़ा विस्तृत व्याख्या के आप हर कदम में कास्टिंग जारी कर सकते हैं:

projects = JSON.parse(response.body) as Array 
projects.each do |project| 
    project = project as Hash 
    project = project["project"] as Hash 
    id = project["id"] as Int 
    name = project["name"] as String 
end 

लेकिन अगर अपने एपीआई प्रतिक्रिया एक प्रसिद्ध संरचना है, मैं दृढ़ता से आप JSON का उपयोग करने का सुझाव । मैपिंग: https://crystal-lang.org/api/0.22.0/JSON.html#mapping-macro

संबंधित मुद्दे