Проблемы, повторяющиеся по хешу в Ruby

Я хотел бы передать хеш хэшей, который выглядит примерно так:

input = {
    "configVersion" => "someVers",
    "box" => 
    {
        "primary"  => {
            "ip" => "192.168.1.1", 
            "host" => "something"
            },
        "api" => {
            "live" => "livekey", 
            "test" => "testkey"
            }
    }
}

затем выполните итерацию по нему, продолжая, если значение является другим хешем, и сгенерировав вывод с ним. Результат должен быть примерно таким:

configVersion = "someVers"
box.primary.ip = "192.168.1.1"
box.primary.host = "something"

и так далее...

Я знаю, как пролистать и продолжить, если значение является хешем, но я не уверен, как объединить все вместе и передать значение обратно. Вот мой код:

def crawl(input)
  input.each do |k,v|
    case v
    when Hash
      out < "#{k}."
      crawl(v)
    else
      out < " = '#{v}';"
    end
  end
end

Моя проблема: где определить out и как вернуть все обратно. Я очень плохо знаком с Руби.

2 ответа

Решение

Вы можете передавать строки между несколькими вызовами рекурсивного метода и использовать их как аккумуляторы.

Этот метод использует ancestors строка для построения вашей строки с точечной нотацией ключей и вывода str который собирает выходные данные и возвращает их в конце метода. str передается через каждый звонок; chain переменная является модифицированной версией ancestor строка, которая изменяется от вызова к вызову:

def hash_to_string(hash, ancestors = "", str = "")
  hash.each do |key, value|
    chain = ancestors.empty? ? key : "#{ancestors}.#{key}"
    if value.is_a? Hash
      hash_to_string(value, chain, str)
    else
      str << "#{chain} = \"#{value}\"\n"
    end
  end
  str
end

hash_to_string input

(Предполагается, что вы хотите, чтобы ваш вывод представлял собой строку, отформатированную как показано выше)

Этот блог имеет достойное решение для рекурсии и предлагает несколько лучшую альтернативу, используя method_missing метод доступен в Ruby.

В целом, ваша рекурсия верна, вы просто хотите делать что-то другое, а не объединять вывод в out,

Другие вопросы по тегам