如何在 Ruby 中将 JSON 对象附加在一起
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13990523/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to append JSON objects together in Ruby
提问by SteveO7
I am trying to create a group of map markers with the results of to_gmaps4railsin an eachblock. On an array with valid geo coordinates the to_gmaps4railsmethod produces valid JSON.
我正在尝试to_gmaps4rails使用each块中的结果创建一组地图标记。在具有有效地理坐标的数组上,该to_gmaps4rails方法生成有效的 JSON。
I'm using Mongoid and my geo coordinates are in a sub-collection like so:
我正在使用 Mongoid,我的地理坐标位于子集合中,如下所示:
Account.locations.coordinates
Here is my controller code. nearby_salesis a collection of Accounts:
这是我的控制器代码。nearby_sales是一个集合Accounts:
@json = String.new
nearby_sales.each do |sale|
@json << sale.locations.to_gmaps4rails
end
The browser complains about my @jsonnot being well-formed.
Is there a Ruby way to append valid JSON together?
浏览器抱怨我的@json格式不正确。有没有一种 Ruby 方法可以将有效的 JSON 附加在一起?
回答by the Tin Man
You can't concatenate JSON formatted strings returned by to_gmaps4railsbecause they won't result in a valid object once decoded.
您不能连接由 返回的 JSON 格式的字符串,to_gmaps4rails因为它们在解码后不会产生有效的对象。
If I have some objects I want to send:
如果我有一些要发送的对象:
loc1 = {"longitude" => "2.13012", "latitude" => "48.8014"}
loc2 = {"longitude" => "-90.556", "latitude" => "41.0634"}
And convert them to JSON like to_gmaps4railsdoes:
并将它们转换为 JSON,如下所示to_gmaps4rails:
loc1_json = loc1.to_json
=> "{\"longitude\":\"2.13012\",\"latitude\":\"48.8014\"}"
loc2_json = loc2.to_json
=> "{\"longitude\":\"-90.556\",\"latitude\":\"41.0634\"}"
They're two JSON-encoded objects as strings.
它们是两个 JSON 编码的字符串对象。
Concatenate the resulting strings:
连接结果字符串:
loc1_json + loc2_json
=> "{\"longitude\":\"2.13012\",\"latitude\":\"48.8014\"}{\"longitude\":\"-90.556\",\"latitude\":\"41.0634\"}"
And send them to another app with a JSON decoder, I'll get:
并将它们发送到另一个带有 JSON 解码器的应用程序,我将得到:
JSON[loc1_json + loc2_json]
JSON::ParserError: 743: unexpected token at '{"longitude":"-90.556","latitude":"41.0634"}'
The parser only makes it through the string partway before it finds a closing delimiter and knows there's an error.
解析器仅在它找到结束分隔符并知道存在错误之前中途通过字符串。
I can wrap them in an array or a hash, and then encode to JSON again, but that doesn't help because the individual JSON strings will have been encoded twice, and will need to be decoded twice again to get back the original data:
我可以将它们包装在数组或散列中,然后再次编码为 JSON,但这无济于事,因为单个 JSON 字符串将被编码两次,并且需要再次解码两次以取回原始数据:
JSON[([loc1_json, loc2_json]).to_json]
=> ["{\"longitude\":\"2.13012\",\"latitude\":\"48.8014\"}",
"{\"longitude\":\"-90.556\",\"latitude\":\"41.0634\"}"]
JSON[([loc1_json, loc2_json]).to_json].map{ |s| JSON[s] }
=> [{"longitude"=>"2.13012", "latitude"=>"48.8014"},
{"longitude"=>"-90.556", "latitude"=>"41.0634"}]
It's not a situation a JSON decoder expects, so that'd require some funky JavaScript on the client side to use the magic JSON decoder-ring twice.
这不是 JSON 解码器所期望的情况,因此客户端需要一些时髦的 JavaScript 才能使用神奇的 JSON 解码器环两次。
The real solution is to decode them back to their native Ruby objects first, then re-encode them into the array or hash, then send them:
真正的解决方案是首先将它们解码回它们的原生 Ruby 对象,然后将它们重新编码为数组或散列,然后发送它们:
array_of_json = [loc1_json, loc2_json].map{ |s| JSON[s] }.to_json
=> "[{\"longitude\":\"2.13012\",\"latitude\":\"48.8014\"},{\"longitude\":\"-90.556\",\"latitude\":\"41.0634\"}]"
The values are correctly encoded now and can be sent to the destination browser or app, which can then make sense of the resulting data, not as an array of strings as above, but as an array of hashes of data:
这些值现在被正确编码,可以发送到目标浏览器或应用程序,然后可以理解结果数据,而不是作为上面的字符串数组,而是作为数据散列数组:
JSON[array_of_json]
=> [{"longitude"=>"2.13012", "latitude"=>"48.8014"},
{"longitude"=>"-90.556", "latitude"=>"41.0634"}]
loc1 == JSON[array_of_json][0]
=> true
loc2 == JSON[array_of_json][1]
=> true
Applying that to your code, here's what needs to be done:
将其应用到您的代码中,需要执行以下操作:
@json = []
nearby_sales.each do |sale|
@json << JSON[sale.locations.to_gmaps4rails]
end
@json.to_json
This decodes the locations back to their "pre-JSON" state, appends them to the array, then returns the array in JSON format.
这会将位置解码回其“JSON 前”状态,将它们附加到数组,然后以 JSON 格式返回数组。
回答by SteveO7
require 'json'
@json = Array.new
nearby_sales.each do |sale|
@json << sale.locations.to_gmaps4rails
end
@json.to_json
回答by Maysam Torabi
You can always try this
你可以试试这个
array_of_json.reduce({}){|z,x| z.merge(x)}

