如何根据键数组在哈希中查找值?

时间:2017-07-06 19:06:22

标签: arrays ruby hash key

使用Ruby(2.4),我想扩展核心哈希功能,以便根据数组搜索键,并返回可从该数组中找到的第一个元素的值。我在我的lib / core_ext / hash_with_indifferent_access.rb文件中有这个......

class CaseInsensitiveHash < HashWithIndifferentAccess
  # This method shouldn't need an override, but my tests say otherwise.
  def [](key)
    if key.kind_of?(Array)
      find_by_arr(arr)
    else
      super convert_key(key)
    end
  end

  protected

  def convert_key(key)
    key.respond_to?(:downcase) ? key.downcase : key
  end

  def find_by_arr(arr)
    arr.inject(self){|h, k| h.to_h[k]}
  end

end

但是,它没有按预期工作。在我的下面的代码中,搜索&#39; h [[&#34; a&#34;,&#34; b&#34;]]&#39;应该生成&#34; 1&#34;,因为第一个元素&#34; a&#34;,是我的哈希中的一个键。

2.4.0 :001 > h = {"a" => 1, "b" => 2}
 => {"a"=>1, "b"=>2}
2.4.0 :002 > h["a"]
 => 1
2.4.0 :003 > h[["a", "b"]]
 => nil

如何修改我的代码,以便我可以将数组作为哈希的键传入,它将开始迭代地搜索数组中的每个元素?

1 个答案:

答案 0 :(得分:1)

你几乎得到了它,但问题是h = { ... }创建了一个普通的Hash,而不是你添加这些方法的那种。

第一个解决方法是:

h = CaseInsensitiveHash["a" => 1, "b" => 2]

然后你得到正确类型的对象,你的方法实际运行。

你的[]方法中有一个错误,可以纠正:

def [](key)
  case key
  when Array
    find_by_arr(key)
  else
    super convert_key(key)
  end
end

您对arr的引用不起作用,因为它没有定义。

find_by_arr方法也返回最后一个匹配,而不是第一个匹配。这可以修复:

def find_by_arr(arr)
  self[arr.first { |key| self[key] }]
end