我正在尝试处理JSON文件:
{ "features": { "additional-options": true },"values": { "lo-value": 34,"hi-value": 554 },"persons": [ { "name": "john","member": true,"current": false,"sponsor": "pete","profile": "","credits": ["04"],"linked": ["philip","guy"],"maptools": ["crossfit","soccer","running"] },{ "name": "mary","sponsor": "judy","credits": ["all"],"activities": ["swimming","cycling","running"] } ],"data_map": [1122,3234] }
我希望能够:
我已经尝试了很多这样的事情来做到这一点.
我的简化代码理念是:
require 'json' hash = JSON.parse(File.read('test.json')) # Add key & value or change existing one def change_key(hash,key,value) keys = key.strip(".") hash[*keys] = value end def add_to_array(hash,val) keys = key.strip(".") hash[*keys] = locate_arr(hash,key).insert(val) end # Delete a key and it's value def del_key(hash,key) keys = key.strip(".") hash[*keys].delete[-1] end def del_from_array(hash,key).delete[-1] end f = File.write('test.json') ; f.puts JSON.pretty_generate(hash) change_key(hash,"features.additional-options",false) del_from_array(hash,"persons.name=mary.activities","cycling") add_to_array(hash,"hockey") del_key(hash,"data_map") del_key(hash,persons.name=john.profile) del_key(hash,persons.name=mary.credits)
生成的JSON应该是:
{ "features": { "additional-options": false },"running","hockey"] } ] }
我不确定如何使用结构如下的JSON.
解决方法
我知道您的JSON可能如下所示:
"{\"features\":{\"additional-options\":true},\"values\":{\"lo-value\":34,\"hi-value\":554},\"persons\":[{\"name\":\"john\",\"member\":true,\"current\":false,\"sponsor\":\"pete\",\"profile\":\"\",\"credits\":[\"04\"],\"linked\":[\"philip\",\"guy\"],\"maptools\":[\"crossfit\",\"soccer\",\"running\"]},{\"name\":\"mary\",\"sponsor\":\"judy\",\"credits\":[\"all\"],\"activities\":[\"swimming\",\"cycling\",\"running\"]}],\"data_map\":[1122,3234]}"
我建议使用OpenStruct来整理您的数据:
your_struct_name = JSON.parse(yourJson,object_class: OpenStruct)
然后你得到你想要的所有东西.对于您显示的操作:
#change_key(hash,false) your_struct_name.features['additional-options'] = false #this one above you set in this hash-like manner because of the '-' in the middle of the key. Otherwise you could just do your_struct_name.features.additional_options = false #del_from_array(hash,"cycling") your_struct_name.persons.last.activities.delete('swimming') # or selecting by name: your_struct_name.persons.select {|person| person.name == 'mary' }.first.activities.delete('swimming') #add_to_array(hash,"hockey") your_struct_name.persons.last.activities << 'hockey' #del_key(hash,"data_map") your_struct_name.delete_field('data_map') #del_key(hash,persons.name=john.profile) ... #del_key(hash,persons.name=mary.credits) ...
然后,在进行更改后,您可以使用:
your_struct_name.to_h.to_json
您还可以使用方法as_json来获得与您在问题上显示的结构非常相似的结构:
your_struct_name.as_json
OpenStruct非常适合处理具有不断变化的结构的数据.如果您有可以“建模”的数据,有一个可以调用的名称,有一些您可以预测的属性,甚至是您将用于此数据的方法,我建议您创建一个类来描述这些数据,它的属性和属性(它甚至可以从OpenStruct继承).然后在这个类域内工作,创建一个抽象层.这样,您的代码就变得更加健壮和可读.不要忘记创建自动测试!它可以为您节省大量时间.
组织和抽象数据的方式,特别是命名实体的方式,对代码质量有很大影响.
如需进一步阅读,请参阅:Object和ActiveData.