如何 select 来自 JSON 文件的对象并在它们未通过 API 验证时推入新文件

How to select objects from JSON file and push into new file when they fail API validation

我正在使用一个 API,它接受一些 JSON 对象(作为 post 请求发送)并根据某些标准使其他对象失败。

我正在尝试编译 "log" 个失败的对象和已成功验证的对象,因此我不必每次都手动复制和粘贴它们。 (有数百个对象)。

基本上如果 API returns "false",我想将该对象推入一个文件,如果 returns 为真,所有这些对象都会进入另一个文件文件。

我曾尝试阅读大量关于 "select, detect, reject" 等枚举器的文档/博客,但我的问题与给出的示例有很大不同。

我在下面的 ruby 文件中编写了一些伪代码,我认为我的方向是正确的,但需要一些指导才能完成任务:

restaurants = JSON.parse File.read('pretty-minified.json')

restaurants.each do |restaurant|
create_response = HTTParty.post("https://api.hailoapp.com/business/create",
{
  :body => restaurant.to_json,
  :headers => { "Content-Type" => "text", "Accept" => "application/x-www-form-urlencoded", "Authorization" => "token #{api_token}" }
  })
  data = create_response.to_hash
  alert = data["valid"]
  if alert == false
    # select restaurant json objects which return false and push into new file
    # false_rest = restaurants.detect { |r| r == false }
    File.open('false_objects.json', 'w') do |file|
      file << JSON.pretty_generate(false_rest)
    else
    # select restaurant json objects which return true and push into another file
    File.open('true_objects.json', 'w') do |file|
      file << JSON.pretty_generate()
  end 

end

API 的输出 (JSON) 示例如下:

{"id":"102427","valid":true}
{"valid":false}

JSON 文件基本上是一个巨大的散列(或对象)数组,这里是一个简短的摘录:

[
  {
    "id": "223078",
    "name": "3 South Place",
    "phone": "+442032151270",
    "email": "3sp@southplacehotel.com",
    "website": "",
    "location": {
      "latitude": 51.5190536,
      "longitude": -0.0871038,
      "address": {
        "line1": "3 South Place",
        "line2": "",
        "line3": "",
        "postcode": "EC2M 2AF",
        "city": "London",
        "country": "UK"
      }
    }
  },
  {
    "id": "210071",
    "name": "5th View Bar & Food",
    "phone": "+442077347869",
    "email": "waterstones.piccadilly@elior.com",
    "website": "http://www.5thview.com",
    "location": {
      "latitude": 51.5089594,
      "longitude": -0.1359897,
      "address": {
        "line1": "Waterstone's Piccadilly",
        "line2": "203-205 Piccadilly",
        "line3": "",
        "postcode": "W1J 9HA",
        "city": "London",
        "country": "UK"
      }
    }
  },
  {
    "id": "239971",
    "name": "65 & King",
    "phone": "+442072292233",
    "email": "hello@65king.com",
    "website": "http://www.65king.com/",
    "location": {
      "latitude": 51.5152533,
      "longitude": -0.1916538,
      "address": {
        "line1": "65 Westbourne Grove",
        "line2": "",
        "line3": "",
        "postcode": "W2 4UJ",
        "city": "London",
        "country": "UK"
      }
    }
  }
]

假设您要按以 elior.com 结尾的电子邮件进行过滤(此条件可能很容易更改):

注意!上面的数据看起来像一个 javascript 变量,它不是一个有效的 ruby 对象。我假设你只是从某个地方以字符串的形式得到它。这就是为什么 json:

require 'json'
array = JSON.parse(restaurants) # data is a string: '[{....... as you received it
result = array.group_by do |e|
  # more sophisticated condition goes here 
  e['email'] =~ /elior\.com$/ ? true : false
end
File.open('false_objects.json', 'w') do |file|
  file << JSON.pretty_generate(result[false])
end
File.open('true_objects.json', 'w') do |file|
  file << JSON.pretty_generate(result[true])
end

result中有一个散列,包含两个元素:

#⇒ { 
#     true: [..valids here ..],
#     false: [..invalids here..]
# }