Как рекурсивно преобразовать файл 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'
}

person koonse    schedule 22.10.2013    source источник
comment
Ответ будет «не легко». Зачем тебе этот хэш?   -  person Ryan Bigg    schedule 22.10.2013
comment
Я использую файлы YAML для i18n в приложении Rails. Но я также использую Polyglot для выполнения i18n в JavaScript, для которого нужен JSON. github.com/airbnb/polyglot.js   -  person koonse    schedule 22.10.2013


Ответы (2)


Поскольку вопрос касается использования файлов YAML для i18n в приложении Rails, стоит отметить, что гем i18n предоставляет вспомогательный модуль 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"
}
person wjordan    schedule 06.07.2018

Рекурсивный ответ @Ryan - это то, что нужно, я просто сделал его немного более рубиновым:

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 для хэша.

person hirolau    schedule 22.10.2013