从yaml文件中读取数据并在ruby中生成一个数组

时间:2012-01-10 06:41:09

标签: ruby yaml

我在yaml文件中有以下数据 -

---
- :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

我需要从这个文件中读取数据并生成一个输出,如下所示 - 对于主题1,它将是这样的,因为它没有技能水平。意味着数组的第一个元素是null。

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

对于第二个主题,它将是这样的 -

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

我正在使用这些值来生成一个prawn pdf表。任何帮助是极大的赞赏。

我试过这个 -

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

干杯!!

2 个答案:

答案 0 :(得分:14)

首先,您的yaml文件不正确YAML,您不能拥有这样的密钥,如果您有空间或奇怪的东西,您需要引用它们,以及开头的内容是什么?< / p>

"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

然后你需要正确加载文件。您在YAML模块上调用方法load_file。 No :: for 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

答案 1 :(得分:6)

在为数据构建YAML文件时,尤其是复杂的数据结构时,我让YAML为我生成它。然后我根据需要进行调整:

require 'yaml'
require 'pp'

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

当我运行该代码时,我得到了这个输出:

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

您可以通过生成YAML来证明数据是正确生成的,然后立即解析代码并显示它看起来像返回的结构,让您进行比较,并通过相等检查:

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

哪个会输出:

[["Skill 1", "Act 1", "B"], ["", "Act 2B"], ["Skill 2", "Act 1", "B"]]
foo == bar: true