如何将一个YAML文件递归展开为一个JSON对象,其中键是点分隔的字符串?

9
例如,如果我有一个包含YAML文件的代码块:

en:
  questions:
    new: 'New Question'
    other:
      recent: 'Recent'
      old: 'Old'

这将以JSON对象形式结束,例如:
{
  'questions.new': 'New Question',
  'questions.other.recent': 'Recent',
  'questions.other.old': 'Old'
}

2
答案将是“不容易”。为什么你需要这个哈希? - Ryan Bigg
我在Rails应用程序中使用YAML文件进行i18n。但是我还使用Polyglot在JavaScript中进行i18n,需要JSON格式的文件。https://github.com/airbnb/polyglot.js - koonse
3个回答

9
require 'yaml'

yml = %Q{
en:
  questions:
    new: 'New Question'
    other:
      recent: 'Recent'
      old: 'Old'
}

yml = YAML.load(yml)
translations = {}

def process_hash(translations, current_key, hash)
  hash.each do |new_key, value|
    combined_key = [current_key, new_key].delete_if { |k| k.blank? }.join('.')
    if value.is_a?(Hash)
      process_hash(translations, combined_key, value)
    else
      translations[combined_key] = value
    end
  end
end

process_hash(translations, '', yml['en'])
p translations

9

由于这个问题是关于在Rails应用中使用YAML文件进行i18n的,值得注意的是i18n gem提供了一个帮助模块I18n::Backend::Flatten,它可以像这样精确地展开翻译:

test.rb

require 'yaml'
require 'json'
require 'i18n'

yaml = YAML.load <<YML
en:
  questions:
    new: 'New Question'
    other:
      recent: 'Recent'
      old: 'Old'
YML
include I18n::Backend::Flatten
puts JSON.pretty_generate flatten_translations(nil, yaml, nil, false)

输出:

$ ruby test.rb
{
  "en.questions.new": "New Question",
  "en.questions.other.recent": "Recent",
  "en.questions.other.old": "Old"
}

6

@Ryan的递归答案是正确的方法,我只是让它更加符合Ruby的风格:

yml = YAML.load(yml)['en']

def flatten_hash(my_hash, parent=[])
  my_hash.flat_map do |key, value|
    case value
      when Hash then flatten_hash( value, parent+[key] )
      else [(parent+[key]).join('.'), value]
    end
  end
end

p flatten_hash(yml) #=> ["questions.new", "New Question", "questions.other.recent", "Recent", "questions.other.old", "Old"]
p Hash[*flatten_hash(yml)] #=> {"questions.new"=>"New Question", "questions.other.recent"=>"Recent", "questions.other.old"=>"Old"}

然后,要将其转换为 JSON 格式,您只需要调用“json”并在哈希上调用 to_json 方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接