JSON 数据到 Ruby 中的实例变量

JSON data to instance variable in Ruby

这是我的 ruby 代码/JSON 文件。需要三个功能,我已经实现了前两个,但在使用第三个时遇到了问题。我最近才开始学习 ruby - 非常感谢任何简化的 explanations/answers

class Company
  attr_accessor :jobs
  jobs = Array.new 

  ## TODO: Implement this method to load the given JSON file into Ruby built-in data
  ## structures (hashes and arrays).
  def self.load_json(filepath)
    require 'json'
    file = File.read(filepath)
    data_hash = JSON.parse(file)
  end

  ## TODO: This method should update the `jobs` property to an array of instances of
  ## class `Job`
  def initialize(filepath)
    # Load the json file and loop over the jobs to create an array of instance of `Job`
    # Assign the `jobs` instance variable.
    load_json(filepath)
    data_hash.each { |jobs|
    array_of_jobs.insert(jobs['name'])
    }
  end

  ## TODO: Impelement this method to return applicants from all jobs with a
  ## tag matching this keyword
  def find_applicants(keyword)
    # Use the `jobs` instance variable.

  end
end

下面是我应该从中检索信息的 JSON 文件代码。

{
  "jobs": [
    {
      "id": 1,
      "title": "Software Developer",
      "applicants": [
        {
          "id": 1,
          "name": "Rich Hickey",
          "tags": ["clojure", "java", "immutability", "datomic", "transducers"]
        },
        {
          "id": 2,
          "name": "Guido van Rossum",
          "tags": ["python", "google", "bdfl", "drop-box"]
        }
      ]
    },
    {
      "id": 2,
      "title": "Software Architect",
      "applicants": [
        {
          "id": 42,
          "name": "Rob Pike",
          "tags": ["plan-9", "TUPE", "go", "google", "sawzall"]
        },
        {
          "id": 2,
          "name": "Guido van Rossum",
          "tags": ["python", "google", "bdfl", "drop-box"]
        },
        {
          "id": 1337,
          "name": "Jeffrey Dean",
          "tags": ["spanner", "BigTable", "MapReduce", "deep learning", "massive clusters"]
        }
      ]
    }
  ]
}

这里是 find_applicants 的简单实现。 JSON 对象可以像任何其他数据结构一样迭代。

Ideone example here.

def find_applicants(myJson, keyword)
    names = []
    myJson["jobs"].each do |job|

        job["applicants"].each do |applicant|
           tags = applicant["tags"]
           if tags.include? keyword then
               names << applicant["name"]
           end  
        end
    end
    names
end

你提供的代码不会编译,使用的方法不是很方便。 您可以遵循的实施步骤:

首先实现你的模型。可能看起来像:

class Applicant
  attr_accessor :id, :name, :tags

  def initialize(id, name=nil, tags=nil)
    @id = id
    @name = name
    @tags = tags
  end
end

class Job
  attr_accessor :id, :title, :applicants

  def initialize(id, title=nil, applicants=nil)
    @id = id
    @title = title
    @applicants = applicants
  end
end

然后定义您的公司 class 与工作

class Company
  attr_accessor :jobs

  def initialize(jobs)
    @jobs = jobs
  end

  def find_applicants(keyword)
    # Now you can iterate through jobs, 
    # job's applicants and finally applicant's tags
    # like this
    applicants = []
    @jobs.each do |job|
      job.applicants.each do |applicant|
        applicant.tags.each do |tag|
          if keyword.eql? tag
             # ...
          end
        end
      end
    end
    applicants
  end
end

然后您可以从 Json 文件加载数据并构造适当的对象:

require 'json'

class DataLoader
  def load(filepath)
    hash = JSON.parse(filepath)
    construct(hash)
  end

  private

  def validate(hash)
    # validate your data here
  end

  def construct(hash)
    validate(hash)
    jobs = []
    hash['jobs'].each do |job|
      applicants = []
      job['applicants'].each do |applicant|
        applicants << Applicant.new(applicant['id'], applicant['name'], applicant['tags'])
      end
      jobs << Job.new(job['id'], job['title'], applicants)
    end
    jobs
  end
end

加在一起看起来像:

tag = 'google'

data = DataLoader.new.load(File.read('data.json'))
company = Company.new(data)
applicants = company.find_applicants(tag)

puts "Applicants that have '#{tag}' in taglist"
applicants.each do |applicant|
  puts "  #{applicant.id}: #{applicant.name}"
end

#Applicants that have google in taglist
#  2: Guido van Rossum
#  42: Rob Pike