Denny Mueller
Denny Mueller

Reputation: 3615

Iterate a yaml array with ruby

I applied YAML.load_file to my example file:

---
languages:
  - name: "English"
    iso_639: "en"
    native_name: "English"
    region:
      - ''
      - UK
      - US
  - name: "Klingon"
    iso_639: "tlh"
    native_name: "tlhIngan Hol"
    region:
      - notearth

I want to iterate though these languages and the region arrays. This doesn't work:

records.each do |record|
  record.region.each do |region|
    self.create!
  end
end

record.region gives me an unknown method error for region. How can I iterate though the languages and and their regions? Or, how can I access the region array?

Upvotes: 3

Views: 8491

Answers (3)

toro2k
toro2k

Reputation: 19238

There are two errors in your code:

  1. The object you get after loading the YAML file is not an array, it's a hash, say the file is called foo.yml:

    YAML.load_file('foo.yml')
    # => {"languages"=>[{"name"=>"English", "iso_639"=>"en", ...
    

    Thus you have to modify your code like the following to make it work:

    records['languages'].each do |record|
      # ...
    
  2. region is not a method of the hash record, it is a key, you have to access the related value using record['region'].

The correct code you have to use is:

records['languages'].each do |record|
  record['region'].each do |region|
    # My guess is you are going to use `region` inside this block
    self.create!
  end
end

Upvotes: 3

BroiSatse
BroiSatse

Reputation: 44715

Yaml is loaded into a hash, hence it will be in form:

languages: [
{
  name: "English"
  iso_639: "en"
  native_name: "English"
  region: ['', 'UK', 'US']
}
{
  name: "Klingon"
  iso_639: "tlh"
  native_name: "tlhIngan Hol"
  region: ['notearth']
}]

So you need to iterate like:

results = YAML.load_file(file)
results['languages'].flat_map{|l| l['region']}.each do |region|
  self.create!
end

Upvotes: 2

Kumar Akarsh
Kumar Akarsh

Reputation: 4980

CONFIG = YAML.load_file("file.yml")
puts CONFIG # {"languages"=>[{"name"=>"English", "iso_639"=>"en", "native_name"=>"English", "region"=>["", "UK", "US"]}, {"name"=>"Klingon", "iso_639"=>"tlh", "native_name"=>"tlhIngan Hol", "region"=>["notearth"]}]}

CONFIG['languages'].map{|l| l['region']}

Upvotes: 0

Related Questions