【问题标题】:Create Yaml without file创建没有文件的 Yaml
【发布时间】:2016-01-25 15:09:59
【问题描述】:

由于一些黑暗的原因,我必须将一个特定的格式化数组转换为哈希,一个解决方案是通过 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 吗?

【问题讨论】:

  • 我猜你忘了运行yml_text = yml_text.join("\n"),你能告诉我们YAML.load(yml_text)之前yml_text的值吗

标签: ruby-on-rails ruby yaml


【解决方案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

【讨论】:

  • 感谢您为我提供了一个没有 YAML 的解决方案,它比我预期的要快。
  • NP。这是一个有趣的挑战,我认为它会更有效率。
【解决方案2】:
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"]}}}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多