how to parse and iterate a json using ruby

时间:2016-08-31 18:22:53

标签: json ruby

Im a beginner with ruby and learning to iterate and parse json file. The contents inside input.json

[
 {
        "scheme": "http",
        "domain_name": "www.example.com",
        "path": "path/to/file",
        "fragment": "header2"
    },
    {
        "scheme": "http",
        "domain_name": "www.example2.org",
        "disabled": true
    },
    {
        "scheme": "https",
        "domain_name": "www.stack.org",
        "path": "some/path",
        "query": {
            "key1": "val1",
            "key2": "val2"
        }
    }
]

ho do I parse print the output as:

http://www.example.com/path/to/file#header2
https://www.stack.org/some/path?key1=val1&key2=val2

Any learning references would be very helpful.

2 个答案:

答案 0 :(得分:2)

Hopefully this code is self-explanatory:

require 'URI'
require 'json'

entries = JSON.parse(File.read('input.json'))
entries.reject { |entry| entry["disabled"] }.each do |entry|
  puts URI::Generic.build({
    :scheme => entry["scheme"],
    :host => entry["domain_name"],
    :fragment => entry["fragment"],
    :query => entry["query"] && URI.encode_www_form(entry["query"]),
    :path => entry["path"] && ("/" + entry["path"])
  }).to_s
end

# Output:
# http://www.example.com/path/to/file#header2
# https://www.stack.org/some/path?key1=val1&key2=val2

答案 1 :(得分:1)

The first step is to turn this JSON into Ruby data:

require 'json'

data = JSON.load(DATA)

Then you need to iterate over this and reject all those that are flagged as disabled:

data.reject do |entry|
  entry['disabled']
end

Which you can chain together with an operation that leverages the URI library to build your output:

require 'uri'

uris = data.reject do |entry|
  entry['disabled']
end.map do |entry|
  case (entry['scheme'])
  when 'https'
    URI::HTTPS
  else
    URI::HTTP
  end.build(
    host: entry['domain_name'],
    path: normalized_path(entry['path']), 
    query: entry['query'] && URI.encode_www_form(entry['query'])
  ).to_s
end

#=> ["http://www.example.com/path/to/file", "http://www.stack.org/some/path?key1=val1&key2=val2"]

This requires a function called normalized_path to deal with nil or invalid paths and fix them:

def normalized_path(path)
  case (path and path[0,1])
  when nil
    '/'
  when '/'
    path
  else
    "/#{path}"
  end
end