Я пытаюсь создать оболочку API-оболочки и проблемы с преобразованием хэш-ключей в более Rubyish-формат из JSON API возвращается.
JSON содержит несколько слоев вложенности, как хэши, так и массивы. Я хочу, чтобы рекурсивно преобразовать все ключи в snake_case для более удобного использования.
Вот что у меня до сих пор:
def convert_hash_keys(value)
return value if (not value.is_a?(Array) and not value.is_a?(Hash))
result = value.inject({}) do |new, (key, value)|
new[to_snake_case(key.to_s).to_sym] = convert_hash_keys(value)
new
end
result
end
Вышеупомянутый метод вызывает преобразование строк в snake_case:
def to_snake_case(string)
string.gsub(/::/, '/').
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
gsub(/([a-z\d])([A-Z])/,'\1_\2').
tr("-", "_").
downcase
end
В идеале результат будет похож на следующий:
hash = {:HashKey => {:NestedHashKey => [{:Key => "value"}]}}
convert_hash_keys(hash)
# => {:hash_key => {:nested_hash_key => [{:key => "value"}]}}
Я ошибаюсь в рекурсии, и каждая версия такого решения, которое я пробовал, либо не конвертирует символы за пределы первого уровня, либо выходит за борт и пытается преобразовать весь хэш, включая значения.
Попытка решить все это в вспомогательном классе, а не по возможности изменять фактические функции Hash и String.
Спасибо заранее.