无文件创建Yaml

时间:2016-01-25 15:09:59

标签: ruby-on-rails ruby yaml

由于一些黑暗的原因,我必须将特定的格式化数组转换为哈希值,并且解决方案是通过YAML。

在没有创建文件的情况下,我没有通过yaml将数组转换为哈希值,你能帮助我吗?

我的原始阵列可能就像这样:

[
  ["lvl1"],
  [nil,"lvl2"],
  [nil, nil, "lvl3", "value1", "value2", "value3"],
  [nil, "lvl2bis"],
  [nil, nil, "lvl3bis", "value1bis", "value2bis", "value3bis"]
]

我将此数组转换为字符串:

  • 对于字符串

    yml_text = []
    array.each do |line|
      yml_line = line.join(",").gsub(/\G,/, '  ').sub(/,+\z/, ']').sub(/:,+/, ':  [')
      yml_text << yml_line
    end
    yml_text = yml_text.join("\n")
    
  • 对于文件

    f = File.open(yml_file_path, "w")
    array.each do |line|
      yml_line = line.join(",").gsub(/\G,/, '  ').sub(/,+\z/, ']').sub(/:,+/, ':  [')
      f.puts(yml_line)
    end
    f.close
    

我得到了以下结果:

lvl1:
  lvl2:
    lvl3: ["value1", "value2", "value3"]
  lvl2bis:
    lvl3bis: ["value1", "value2", "value3"]

如果我将此文本保存在yml文件中并按照以下方式解析:

hash = YAML.load(File.read(yml_file_path)) 

我得到了哈希:

{ "lvl1" => {
    "lvl2" => {
      "lvl3" => ["value1", "value2", "value3"]
    },
    "lvl2bis" => {
      "lvl3bis" => ["value1bis", "value2bis", "value3bis"]
    }
  }
}

如果我不将此文本保存为yml文件并尝试加载我的yml_text,我会得到:

yml_data = YAML.load(yml_text)
p yml_data
"lvl1 lvl2 lvl3,value1,value2,value3 lvl2bis lvl3bis,value1bis,value2bis,value3bis"

如果不创建文件,是否无法通过YAML?

2 个答案:

答案 0 :(得分:1)

YAML.load(
  inp.map(&:dup).map do |a| # #dup is required for safe #shift below
    count, arr = (0...a.size).each do |i|
      curr = a.shift
      break [i, curr] unless curr.nil?
    end
    "  " * count << arr << ": " << (a.empty? ? "" : a.inspect)
  end.join($/)
)
#⇒ {"lvl1"=>{"lvl2"=>{"lvl3"=>["value1", "value2", "value3"]},
#     "lvl2bis"=>{"lvl3bis"=>["value1bis", "value2bis", "value3bis"]}}}

答案 1 :(得分:1)

这并没有回答你的YAML问题,只是将数组直接转换为哈希:

def to_hash(array)
  default = ->(hash, key) { hash[key] = Hash.new(&default) }
  keys = []
  array.inject(Hash.new(&default)) do |hash, element|
    compacted = element.compact
    if compacted.length > 1
      nested_hash = keys.inject(hash) { |sub_hash, key| sub_hash[key] }
      nested_hash[compacted.shift] = compacted
    else
      keys = keys.take(element.count(nil))
      keys[keys.length] = compacted.shift
    end
    hash
  end
end