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

例如,如果我有YAML文件

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

这最终会像json对象一样

 { 'questions.new': 'New Question', 'questions.other.recent': 'Recent', 'questions.other.old': 'Old' } 

由于问题是关于在Rails应用程序上使用i18n的YAML文件,值得注意的是i18n gem提供了一个帮助器模块I18n::Backend::Flatten ,它完全像这样平移翻译:

test.rb

 require 'yaml' require 'json' require 'i18n' yaml = YAML.load < 

输出:

 $ ruby test.rb { "en.questions.new": "New Question", "en.questions.other.recent": "Recent", "en.questions.other.old": "Old" } 
 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 

@ Ryan的递归答案是要走的路,我只是做了一点Rubyish:

 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方法。