Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Read data from yaml file and produce an array in ruby

Tags:

ruby

yaml

I have the following data in a yaml file -

---
- :Subject_list 
    Subject 1: 
     :Act 1: A
     :Act 2: B
    Subject 2: 
     :Skill 1: 
       :Act 1: B
       :Act 2: B  
     :Skill 2:
       :Act 1: B

I need to read data from this file and and generate an output which is given below - For subject 1 it will be like this as it has no skill level. Meaning the first element of the array is null.

  ["","Act 1", "A"], ["","Act 2", "B"]

For the second subject it will be like this -

  ["Skill 1","Act 1", "B"], ["","Act 2" "B"],["Skill 2","Act 1", "B"]

I am using these values to generate a prawn pdf table. Any help is greatly appreciated.

I tried doing this -

data=YAML::load(File.read("file.yaml"));
subject = data[:Subject_list]
sub_list =["Subject 1", "Subject 2"]

  sub_list.each do |sub|
      sub_data = []
      sub_data = subject["#{sub}"]
         # I convert the list symbol to an array, so i can loop through the sub     activities. 
         #I need some direction here as how to check whether the symbol will be a skill or activity
      end

Cheers!!

like image 961
verdure Avatar asked Jan 10 '12 06:01

verdure


2 Answers

First off, your yaml file is not correct YAML, you cannot have keys like that, if you have space or weirdness in them you need to quote them, and what's up with the : at the beginning?

"Subject_list":
  "Subject 1": 
    "Act 1": A
    "Act 2": B
  "Subject 2": 
    "Skill 1": 
      "Act 1": B
      "Act 2": B  
    "Skill 2":
      "Act 1": B

Then you need to load the file properly. You call the method load_file on the YAML module. No :: for method access in ruby afaik.

require 'yaml'
data = YAML.load_file "file.yaml"
subject = data["Subject_list"]

require 'pp'
subject.each do |s|
  item = s.last
  if item.keys.first =~ /Skill/
    pp item.keys.inject([]) { |memo,x| item[x].map { |i| memo << i.flatten.unshift(x) } ; memo}
  else
    pp item.map { |k,v| ["", k, v] }
  end
end
like image 56
sunkencity Avatar answered Oct 21 '22 20:10

sunkencity


When building up a YAML file for data, especially a complex data structure, I let YAML generate it for me. Then I tweak as necessary:

require 'yaml'
require 'pp'

foo = ["Skill 1","Act 1", "B"], ["","Act 2" "B"],["Skill 2","Act 1", "B"]
puts foo.to_yaml

When I run that code I get this output:

--- 
- - Skill 1
  - Act 1
  - B
- - ""
  - Act 2B
- - Skill 2
  - Act 1
  - B

You can prove the data is correctly generated by having YAML generate, then immediately parse the code and show what it looks like as the returned structure, letting you compare it, and by an equality check:

bar = YAML.load(foo.to_yaml)
pp bar
puts "foo == bar: #{ foo == bar }"

Which would output:

[["Skill 1", "Act 1", "B"], ["", "Act 2B"], ["Skill 2", "Act 1", "B"]]
foo == bar: true
like image 30
the Tin Man Avatar answered Oct 21 '22 22:10

the Tin Man