【问题标题】:Editing JSON Array contents in Ruby在 Ruby 中编辑 JSON 数组内容
【发布时间】:2014-05-15 20:53:13
【问题描述】:

我的 JSON 数组的结构如下:

{"data":[{"Chris":[{"long":10,"lat":19}]},{"Scott":[{"long":9,"lat":18}]}]}

在 ruby​​ 程序中,我希望能够编辑名称的 lat 和 long 值。但我不太确定该怎么做。

sections.each do |user_coords|
        user_coords.each do |user, coords|
            if user == Usrname then
                #Change lat and long value for Usrname
            end
        end
end

如何做到这一点?

【问题讨论】:

  • 真的需要看看为什么你的哈希值如此复杂。通常定义的散列会更容易导航/修改。照原样,您正在处理一些您很少看到的东西,因此您学习使用它的东西将不适用于普通哈希。只是想一想。

标签: ruby arrays json hash


【解决方案1】:

这是访问 JSON 中单个元素的方法:

require 'json'

foo = JSON['{"data":[{"Chris":[{"long":10,"lat":19}]},{"Scott":[{"long":9,"lat":18}]}]}']
foo['data'][0]['Chris'][0]['long'] = 5
foo['data'][0]['Chris'][0]['lat'] = 7
foo # => {"data"=>[{"Chris"=>[{"long"=>5, "lat"=>7}]}, {"Scott"=>[{"long"=>9, "lat"=>18}]}]}

您可以通过在对象中使用变量作为占位符来简化路径:

foo = JSON['{"data":[{"Chris":[{"long":10,"lat":19}]},{"Scott":[{"long":9,"lat":18}]}]}']
chris = foo['data'][0]['Chris'][0]
chris['long'] = 5
chris['lat'] = 7
foo # => {"data"=>[{"Chris"=>[{"long"=>5, "lat"=>7}]}, {"Scott"=>[{"long"=>9, "lat"=>18}]}]}

chris 指向嵌入在foo 散列中的“Chris”散列。 chris 散列的更改发生在 foo 内部。

如果哈希被正常定义,它会更干净/清晰和直接:

foo = JSON['{"data":{"Chris":{"long":5,"lat":7},"Scott":{"long":9,"lat":18}}}']
foo['data']['Chris']['long'] = 5
foo['data']['Chris']['lat'] = 7
foo # => {"data"=>{"Chris"=>{"long"=>5, "lat"=>7}, "Scott"=>{"long"=>9, "lat"=>18}}}

foo 更明确地定义为:

foo = {
  'data' => {
    'Chris' => {'long' => 5, 'lat' => 7},
    'Scott' => {'long' => 9, 'lat' => 18}
  }
}

有条件地遍历哈希以查找特定的键/值对与您的哈希看起来像这样:

require 'json'

foo = JSON['{"data":[{"Chris":[{"long":10,"lat":19}]},{"Scott":[{"long":9,"lat":18}]}]}']

user_name = 'Chris'
data = foo['data'].first
data.first.each do |key, value|
  if key == user_name
    data[user_name].first['long'] = 5
    data[user_name].first['lat'] = 6
  end
end

foo # => {"data"=>[{"Chris"=>[{"long"=>5, "lat"=>6}]}, {"Scott"=>[{"long"=>9, "lat"=>18}]}]}

不得不使用first(或[0])来获取哈希元素有异味。

使用正确定义的哈希会产生如下代码:

foo = JSON['{"data":{"Chris":{"long":10,"lat":19},"Scott":{"long":9,"lat":18}}}']
foo['data'].each do |key, value| 
  if key == user_name
    value['long'] = 5
    value['lat'] = 7
  end
end
foo # => {"data"=>{"Chris"=>{"long"=>5, "lat"=>7}, "Scott"=>{"long"=>9, "lat"=>18}}}

如何添加另一个叫 Bob 且 long = 10 和 lat = 20 的人

听起来您没有很好地掌握操作/访问哈希,或如何转换为 JSON 或从 JSON 转换。你最好把这些基础知识搞清楚。

不要以 JSON 开头,而是以 Ruby 哈希开头:

require 'json'

foo = {
  "data" => {
    "Chris" => {
      "long" => 5, 
      "lat" => 7
    }, 
    "Scott" => {
      "long" => 9,
      "lat" => 18
    }
  }
}

添加您想要的任何其他哈希元素:

bob_hash = {'Bob' => {'long' => 10, 'lat' => 20}}
foo['data'].merge!(bob_hash)

merge!bob_hash 添加到foo['data']。然后,使用to_json 告诉哈希输出其 JSON 表示。使用熟悉的 Ruby 结构并让 Ruby 完成转换为 JSON 的繁重工作要比尝试对现有 JSON 字符串进行字符串操作要容易得多。如果您有 JSON,则对其进行解析并转换/修改生成的 Ruby 对象,然后再次输出 JSON。

puts foo.to_json
# >> {"data":{"Chris":{"long":5,"lat":7},"Scott":{"long":9,"lat":18},"Bob":{"long":10,"lat":20}}}

我建议您也阅读“How to convert JSON to a hash, search for and change a value”,因为它是访问结果哈希值的有用替代方法。

【讨论】:

  • 我现在已将 JSON 脚本更改为:{"data":{"Chris":{"long":10,"lat":10},"Scott":{"long" :9,"lat":18}}} 如何添加另一个叫 Bob 的人,long = 10 和 lat = 20
  • 真的需要通读一些 Ruby 教程。这是基本的哈希用法 101。
【解决方案2】:
username = 'Chris'
sections.each do |user_coords|
  user_coords.each do |user, coords|
    if user == username then
      coords.each do |lat_long|
        lat_long['lat']  = 123 # Your value here...
        lat_long['long'] = 456 # Your value here...
      end
    end
  end
end
sections.to_json # => '[{"Chris":[{"long":456,"lat":123}]}...]'

【讨论】:

  • 你为什么把最后一行的部分注释掉了?
  • 最后一行显示返回的值。这是许多开发人员使用的 TextMate 和 Sublime 文本编辑器中的一项功能,类似于您在 IRB 中看到的输出。
  • @Cj1m:与其他人共享代码示例以演示语句以及显示返回值的注释(statement # => return value)是一种常见的做法。例如,在 JavaScript 中你可能会说[1,2,3].pop(); // => 3
  • 然后我想将部分添加回“数据”数组,我该怎么做?
猜你喜欢
  • 2010-11-27
  • 2018-01-14
  • 1970-01-01
  • 2014-03-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多