如何在 Ruby 中迭代深度嵌套哈希而不知道深度

1 ruby ruby-on-rails ruby-hash

我有多个 YAML(本地化)文件。我解析它们并转换为 Ruby 中的哈希值。

例如,这是其中之一:

hello: Hallo
messages:
  alerts:
    yay: Da!
    no: Nein
  deep:
    nested:
      another:
        level:
          hi: Hi!
test: Test!
Run Code Online (Sandbox Code Playgroud)

基本上,这看起来像 Rails App 中使用 YAML 的区域设置文件。

我想做的是递归地迭代这个哈希并获取键和值。这样我就可以像 Google Translate 一样从 API 端点一一翻译值。我想将嵌套哈希保留在同一模式中,以便 Rails 可以通过键查找。

我知道我可以使用嵌套循环,但不能保证嵌套哈希的数量是已知的。如何递归地迭代这个哈希以便我可以操纵值(翻译/替换)?

预期结果:(使用 API 调用的翻译服务后

hello: Hello
messages:
  alerts:
    yay: Yup!
    no: No
  deep:
    nested:
      another:
        level:
          hi: Hi!
test: Test!
Run Code Online (Sandbox Code Playgroud)

到目前为止我尝试过的:

hello: Hallo
messages:
  alerts:
    yay: Da!
    no: Nein
  deep:
    nested:
      another:
        level:
          hi: Hi!
test: Test!
Run Code Online (Sandbox Code Playgroud)

但这只是操纵hello而已。为了与其他人一起工作,我必须做一个循环。但嵌套了多少个键尚不清楚。

如何迭代区域设置哈希的所有值并保持架构完整?

如果可能但不是强制性的,如果我们能够在最终结果中保持键的顺序,我会非常高兴。如果稍后在手动检查时找到丢失的密钥,那就太棒了。

我对红宝石很陌生。我正在使用红宝石2.7.2

结论/解决方案

所有答案都是正确的,我喜欢它们。但是,我希望能够同时控制键和值。不仅仅是通过价值观进行转变。因此,我接受了适合我需要的答案。我能够通过选定的答案来实现我的意图。

hmn*_*nhf 5

您可以使用deep_transform_values!哈希对象来递归地更改值。(或其非破坏性版本deep_transform_values,返回新的哈希值而不是更改原始哈希值。)

hash.deep_transform_values! { |value| translate_func(value) }
Run Code Online (Sandbox Code Playgroud)

注意:deep_transform_values!是一个Rails方法。如果您不使用 Rails,请参阅此处的源代码以获得灵感。