我正在尝试处理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", "member": true, "current": false, "sponsor": "judy", "profile": "", "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, key, 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, val) keys = key.strip(".") hash[*keys] = locate_arr(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, "persons.name=mary.activities", "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 }, "values": { "lo-value": 34, "hi-value": 554 }, "persons": [ { "name": "john", "member": true, "current": false, "sponsor": "pete", "credits": ["04"], "linked": ["philip","guy"], "maptools": ["crossfit","soccer","running"] }, { "name": "mary", "member": true, "current": false, "sponsor": "judy", "profile": "", "activities": ["swimming", "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\",\"member\":true,\"current\":false,\"sponsor\":\"judy\",\"profile\":\"\",\"credits\":[\"all\"],\"activities\":[\"swimming\",\"cycling\",\"running\"]}],\"data_map\":[1122,3234]}"
我建议使用OpenStruct来组织数据:
your_struct_name = JSON.parse(yourJson, object_class: OpenStruct)
然后,您得到了所有想要的东西。对于您显示的操作:
#change_key(hash, "features.additional-options", 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, "persons.name=mary.activities", "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, "persons.name=mary.activities", "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来获得与问题所显示的结构非常相似的结构:
as_json
your_struct_name.as_json
OpenStruct处理 结构变化的 数据非常好。如果您具有可以“建模”的数据,可以调用的名称,可以预测的某些属性,甚至可以用于此数据的方法,那么建议您创建一个Class来描述此数据,其属性和属性(甚至可以继承自OpenStruct)。然后在这个Class域内工作,创建一个抽象层。这样,您的代码将变得更加健壮和易读。不要忘记创建自动测试!它为您节省了大量时间。
OpenStruct
组织和抽象数据的方式,特别是命名实体的方式,对代码质量有很大影响。
有关更多信息,请参见:Object和ActiveData。