ruby - 如何将 JSON 转换为散列、搜索和更改值

标签 ruby 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]
}

我希望能够:

  • 更新键值对的值
  • 同时删除键/值
  • 删除或插入一个数组值

为了做到这一点,我尝试了很多方法。

我的简化代码思路是:

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 来获得与您在问题中展示的结构非常相似的结构:

your_struct_name.as_json

OpenStruct 非常适合处理具有不断变化的结构 的数据。如果你有可以“建模”的数据,有一个你可以调用的名字,有一些你可以预测的属性,甚至你将用于这些数据的方法,我建议你创建一个类来描述这个数据,它的属性和属性(它甚至可以继承自 OpenStruct)。然后在这个类域内工作,创建一个抽象层。这样你的代码就会变得更加健壮和可读。不要忘记创建自动测试!它可以为您节省大量时间。

组织和抽象数据的方式,特别是命名实体的方式对代码质量有很大影响。

如需进一步阅读,请参阅:ObjectActiveData .

关于ruby - 如何将 JSON 转换为散列、搜索和更改值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32228126/

相关文章:

javascript - Json 字符串化更改日期

ruby-on-rails - Rails - 嵌套表单不显示 - 在没有另一个 Controller 的情况下填充表格

ruby-on-rails - Ruby:在 block 后调用 'join'

ruby-on-rails - ruby 2.0.0p247 的段错误导致 Rails 服务器崩溃

javascript - 使用 json 在一页上显示多个动态 Highcharts

java - 如何根据请求在 java bean 中动态更改 "constant"值( hibernate )?

mysql - Rails 3 - 突然挂起的迁移错误

windows - IO.popen(my_cmd) - 子进程何时完成?

java - 我的 Spring 应用程序无法识别我的网络服务

javascript - 将 JS 对象字符串化为 JSON(将函数字符串化为属性)