从 Ruby 中的键数组的散列中获取值的方法

Ash*_*Ash 3 ruby arrays hash

我正在尝试编写一个函数,该函数在提供键数组时返回散列键的值(如果键不存在,则返回“nil”)。

考虑哈希:

my_hash = { 
  font_size: 10, 
  font_family: "Arial", 
  boo: { 
    name: 'blah' 
  } 
}
Run Code Online (Sandbox Code Playgroud)

该方法的存根可能是:

def get_value(hash, array_of_keys)
  ...
end
Run Code Online (Sandbox Code Playgroud)

原因是我可以访问散列中可能实际上不存在的不同键。因此,例如,我想要 'blah',通常我会打电话,my_hash[:boo][:name]但它可能不存在或可能很深。我想要做的是拥有我的函数,我可以调用它,get_value(my_hash, [:boo, :name])以便我可以测试每个键是否存在(所以如果它们中的任何一个不存在,我就不会得到异常,以及在哪里无关紧要'深'的价值可能是)。

在我的情况下,检查我需要的每个值的存在是不可行的(我可能需要测试 10 个连续键的存在)我只需要一个函数,我可以说出我需要哪个值并获取该值(如果存在),并且如果不是,则为 nil(因此不会在尝试检索它时抛出异常)。

我试了一下,尝试使用一个递归函数,该函数每次循环时都会弹出数组中的第一个元素,但我无法练习如何返回我的值。

def get_value(val, arr)
  if arr.count > 1
    arr.each do |a|
      get_value val[a], arr.pop
    end
  else
    val[a]
  end
end


get_value s, [:boo, :name]
Run Code Online (Sandbox Code Playgroud)

这是我的尝试(显然不起作用) - 谁能帮我解决这个问题,或者有一个可能更优雅的替代解决方案?几点:

  • 不能保证键存在,在这些情况下我想返回 nil,并且
  • 散列可能非常深,因此它需要处理数组中的任何散列和任意数量的键(这就是为什么我认为递归可能是答案,但现在我不太确定)。

saw*_*awa 5

[:font_size].inject(my_hash){|h, k| h.to_h[k]} #=> 10
[:boo, :name].inject(my_hash){|h, k| h.to_h[k]} #=> "blah"
[:boo, :foo].inject(my_hash){|h, k| h.to_h[k]} #=> nil
Run Code Online (Sandbox Code Playgroud)

  • Ash,考虑sawa 的例子#2。`inject` 有一个由块变量 `h` 给出的备忘录。最初,`h = my_hash`。`:boo` 被传递到块中,并且 `h = (my_hash.to_h)[:boo] = h[:boo] = {name: "blah"}`,因为 `g.to_h => g` 用于任何哈希`g`。接下来,`:name` 被传递到块中,所以 `h = ({name: "blah"}.to_h)[:name] = {name: "blah"}[:name] => "blah"`。由于没有更多元素要传递给块,因此返回“blah”。如果数组改为`[:foo, :name]`、`h = (my_hash.to_h)[:foo] = my_hash[:foo] = nil`,则`h = (nil.to_h)[:name] => {}[:name] => nil`。 (2认同)