如何将JSON转换为哈希,搜索和更改值 [英] How to convert JSON to a hash, search for and change a value
问题描述
我正在尝试处理JSON文件:
I'm trying to process a JSON file:
{
"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]
}
我希望能够:
- 更新键值对上的值
- 删除键/值
- 删除或插入一个数组值
为了达到这个目的,我已经做了很多尝试.
I have tried so many thing to get this right.
我的简化代码思路是:
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应该是:
The resulting JSON should be:
{
"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.
I'm not sure how to work with JSON that is structured like this.
推荐答案
我了解您的JSON可能如下所示:
I understand your JSON may look like this:
"{\"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 来整理数据:
I suggest using an OpenStruct to organize your data:
your_struct_name = JSON.parse(yourJson, object_class: OpenStruct)
然后,您将获得所有想要的东西.对于显示的操作:
Then you get all the things you want. For the operations you show:
#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)
...
然后,进行更改后,可以使用:
Then, after you make your changes, you can use:
your_struct_name.to_h.to_json
您还可以使用方法as_json
来获得与问题所显示的结构非常相似的结构:
You can also use the method as_json
to get a structure very similar to what you showed on the question:
your_struct_name.as_json
OpenStruct
非常适合处理具有不断变化的结构的数据.如果您具有可以建模"的数据,可以调用的名称,可以预测的某些属性,甚至可以用于此数据的方法,那么我建议您创建一个Class来描述此数据,其属性和属性(甚至可以继承自OpenStruct).然后在这个Class域内工作,创建一个抽象层.这样,您的代码将变得更加健壮和易读.不要忘记创建自动测试!它为您节省了很多时间.
OpenStruct
is very nice to deal with data that has a changing structure. If you have data that can be "modeled", has a name you can call, has some attributes you can predict, and even methods you will use for this data, I suggest you to create a Class to describe this data, its properties and attributes (it can even inherit from OpenStruct). Then work inside this Class domain, creating a layer of abstraction. This way your code gets a lot more robust and readable. Don't forget to create automatic tests! It saves you a lot of time.
组织和抽象数据的方式,特别是命名实体的方式,对代码质量有很大影响.
The way you organize and abstract your data, and specially the way you name entities are things that have high impact on code quality.
有关更多信息,请参见:对象和
For further reading see: Object and ActiveData.
这篇关于如何将JSON转换为哈希,搜索和更改值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!