1

我有一个 YAML 文件,其中包含:

cat:
  name: Cat
  description: catlike reflexes
dog:
  name: Dog
  description: doggy breath

我想解析它并将描述分解成key1这样key2

cat:
  name: Cat
  description: catlike reflexes
  info:
    key1: catlike
    key2: reflexes
dog:
  name: Dog
  description: doggy breath
  info:
    key1: doggy
    key2: breath

但是,由于某种原因,我不能正确地做到这一点。到目前为止,我尝试过的是下面代码的变体,我认为我过于复杂了:

# to get the original file's data
some_data = YAML.load(File.open("#{Rails.root}/config/some_data.yml"))

new_data = some_data.collect do |old_animal|
  animal = old_animal.second

  if animal && animal["description"]
    new_blocks = Hash.new
    blocks = animal["description"].split(" ")
    new_blocks["key1"] = blocks.first
    new_blocks["key2"] = blocks.second
    animal["info"] = new_blocks
  end
  old_animal.second = animal
  old_animal
end

# to write over the original file
File.write("#{Rails.root}/config/some_data.yml", new_data.to_yaml)
4

1 回答 1

1

你没有说你是否可以在描述中包含多个单词,但这是一种常识,所以我会做这样的事情:

require 'yaml'

data = YAML.load(<<EOT)
cat:
  name: Cat
  description: catlike reflexes rules
dog:
  name: Dog
  description: doggy breath
EOT
data # => {"cat"=>{"name"=>"Cat", "description"=>"catlike reflexes rules"}, "dog"=>{"name"=>"Dog", "description"=>"doggy breath"}}

此时,来自 YAML 文件的数据被加载到哈希中。遍历每个哈希键/值对:

data.each do |(k, v)|
  descriptions = v['description'].split
  keys = descriptions.each_with_object([]) { |o, m| m << "key#{(m.size + 1)}" }
  hash = keys.each_with_object({}) { |o, m| m[o] = descriptions.shift }
  data[k]['info'] = hash
end

这是我们得到的:

data # => {"cat"=>{"name"=>"Cat", "description"=>"catlike reflexes rules", "info"=>{"key1"=>"catlike", "key2"=>"reflexes", "key3"=>"rules"}}, "dog"=>{"name"=>"Dog", "description"=>"doggy breath", "info"=>{"key1"=>"doggy", "key2"=>"breath"}}}

如果输出它会是什么样子:

puts data.to_yaml
# >> ---
# >> cat:
# >>   name: Cat
# >>   description: catlike reflexes rules
# >>   info:
# >>     key1: catlike
# >>     key2: reflexes
# >>     key3: rules
# >> dog:
# >>   name: Dog
# >>   description: doggy breath
# >>   info:
# >>     key1: doggy
# >>     key2: breath

each_with_object类似于inject但使用起来更简洁,因为它不需要我们返回我们正在累积的对象。

于 2013-07-22T23:29:38.270 回答