如何在读取时清理/转换JSON数据?

时间:2014-08-11 06:00:51

标签: ruby-on-rails ruby json

清理(转换)一个结构严重的JSON哈希数组的清洁和惯用方法是什么,结构如下,假设哈希中的键总是很好?

在此示例中,邮政编码和电话号码采用不同的格式,并且键/值对street_address仅位于其中一个哈希值中。我想要做的是将所有邮政编码传递给帮助者解析邮政编码,通过电话号码清理器传递电话号码,并将街道地址(如果存在的话)传递给自己的解析器。我想保留JSON数组的结构,只是规范化值。

[{      "name": "Person 1",
    "postal_code": "VXXXS",
    "phone_number": "(111)093910",
}, 
{      "name": "Person 2",
    "postal_code": "VX-XXS",
    "phone_number": "++(111)093139",
}, 
{      "name": "Person 3",
    "street_address": "1 Something Rd",
}]

我在考虑迭代每个数组元素,然后使用如下的switch语句:

json.each do |hash|
 hash.keys do |key|
  case key
  when "postal_code"
    hash[key] = postal_code_parser(hash[key])
  when "street_address"
    hash[key] = street_address_parser(hash[key])
  when "phone_number"
    hash[key] = phone_number_parser(hash[key])
  end
 end
end

但这有点难看,我认为这可能是一个普遍的问题,因为存在一种干净,更有效的方法来解决它。我仍然觉得红宝石压倒性的。

1 个答案:

答案 0 :(得分:1)

最简单的方法是明确地通过键调用值:

json.each do |hash|
  hash["postal_code"] = postal_code_parser(hash["postal_code"]) if hash.key?("postal_code")
  hash["street_address"] = street_address_parser(hash["street_address"]) if hash.key?("street_address")
  hash["phone_number"] = phone_number_parser(hash["phone_number"]) if hash.key?("phone_number")
end

每行末尾的if表示如果未设置该键的值,则不会调用代码。

如果您想使其更通用和动态,您可以保留每个密钥的解析器列表:

parsers = {"postal_code" => :postal_code_parser,
           "street_address" => :street_address_parser
           "phone_number" => :phone_number_parser}

json.each do |hash|
  parsers.each do |key, parser|
    hash[key] = send(parser, hash[key]) if hash.key?(key)
  end
end