如何设置任意长度的"关键路径"的Ruby哈希?

B S*_*ven 3 ruby hash

鉴于:

h = {foo: {bar: 1}}
Run Code Online (Sandbox Code Playgroud)

如何设置bar,如果你不知道你有多少个键有哪些?

例如: keys = [:foo, :bar]

h[keys[0]][keys[1]] = :ok
Run Code Online (Sandbox Code Playgroud)

但是如果键可以是任意长度而h是任意深度怎么办?

mu *_*ort 6

如果您使用的是Ruby 2.3+,那么您可以dig这样使用:

h.dig(*keys[0..-2])[keys.last] = :ok
Run Code Online (Sandbox Code Playgroud)

dig跟随一个穿过哈希的路径并返回它找到的内容.但是dig不会复制它找到的内容,所以你得到了相同的引用h.keys[0..-2]抓住所有,但最后一个元素keys,以便h.dig(*keys[0..-2])让您{bar: 1}从内哈希h,那么你就可以用一个简单的任务修改它的地方.

你也可以说:

*head, tail = keys
h.dig(*head)[tail] = :ok
Run Code Online (Sandbox Code Playgroud)

如果这比你更清楚[0..-2].

如果你没有,dig那么你可以做以下事情:

*head, tail = keys
head.inject(h) { |m, k| m[k] }[tail] = :ok
Run Code Online (Sandbox Code Playgroud)

当然,如果你不确定keys存在指定的路径,那么你需要抛出一些nil检查并决定你应该如何处理keys它不指定路径h.

  • 尼斯.我发现`h.dig(*head)[tail] =:ok`更具可读性. (3认同)