将ruby哈希值转换为有效且易读的JSON

时间:2014-04-05 19:51:17

标签: ruby json hash

我的代码有效,但正在征求改进建议。

我有一个包含ruby哈希的文件:

{"dat"=>"2013-09-01T20:40:00-07:00", "sca"=>"5", "del"=>"755", "dir"=>"S"}
{"dat"=>"2013-09-01T21:00:00-07:00", "sca"=>"5", "del"=>"459", "dir"=>"S"}

我想要转换为有效且易读的JSON。此代码是紧凑的,并生成有效的JSON ...

#!/usr/bin/env ruby

# expected input:   file of hashes, one/line
# output:       properly formatted json array

require 'json'

json_array = []

while input = ARGF.gets
    input.each_line do |line|
        json_array.push( eval(line) )   
    end  
end
print json_array
puts

..但没有任何新行不容易被人类阅读:

[{"dat"=>"2013-09-01T20:40:00-07:00", "sca"=>"5", "del"=>"755", "dir"=>"S"}, {"dat"=>"2013-09-01T21:00:00-07:00", "sca"=>"5", "del"=>"459", "dir"=>"S"}]

puts JSON.pretty_generate(json_array)

对于上面的两个输出行,生成了人类可读的有效JSON,但是详细:

[
  {
    "dat": "2013-09-01T20:40:00-07:00",
    "sca": "5",
    "del": "755",
    "dir": "S"
  },

(more lines...)

从人类可读性的角度来看,更好的是拥有一个"记录"在每一行:

[
  {"dat":"2013-09-01T20:40:00-07:00","sca":"5","del":"755","dir":"S"},
  {"dat":"2013-09-01T21:00:00-07:00","sca":"5","del":"459","dir":"S"} 
]

但为了避免尾随逗号问题[显然是一个常见的问题 - 请参阅http://trailingcomma.com/]我采用了一个带有特殊外壳的丑陋循环。虽然它实现了目标,但我对它并不满意,我觉得必须有一个更简单的方法:

#!/usr/bin/env ruby

# expected input:   file of hashes, one/line
# output:       properly formatted json array

require 'json'

prevHash = ""
currHash = ""

puts "["

while input = ARGF.gets
    # in order to to prevent a dangling comma on last element in output json array
    # this counter-intuitive loop always outputs the prev, not the current, array elem
    # with a trailing comma
    input.each_line do |currLine|
        currHash = eval(currLine)   # convert string to hash
        if (prevHash != "")     # if not first time thru
            puts "  " + prevHash.to_json + ","
        end
        prevHash = currHash
    end  
end
# then, finally add the last array element *without* the troublesome trailing comma
puts "  " + currHash.to_json 

puts "]"

欢迎提出建议,特别是那些向我展示我错过的巧妙单行的建议。

1 个答案:

答案 0 :(得分:3)

JSON.pretty_generate接受optional hash parameter,您可以在其中配置生成器。

状态哈希可以包含以下键:

  • 缩进:用于缩进级别的字符串(默认值:“),
  • 空间:放在后面的字符串,a:或分隔符(默认值:“),
  • space_before :放在a:pair分隔符之前的字符串(默认值:“),
  • object_nl :放在JSON对象末尾的字符串(默认值:“),
  • array_nl :放在JSON数组末尾的字符串(默认值:“),
  • allow_nan :如果应生成NaN,Infinity和-Infinity,则为true,否则如果遇到这些值,则会引发异常。此选项默认为false。
  • max_nesting :从中生成JSON的数据结构中允许的最大嵌套深度。禁用深度检查:max_nesting => false,默认为19。

玩弄最接近我能满足你要求的是

JSON.pretty_generate(hash, {object_nl: '', indent: ' '})

呈现为

[
 {  "dat": "2013-09-01T20:40:00-07:00",  "sca": "5",  "del": "755",  "dir": "S"},
 {  "dat": "2013-09-01T21:00:00-07:00",  "sca": "5",  "del": "459",  "dir": "S"}
]