使用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
如何修改我的代码,以便我可以将数组作为哈希的键传入,它将开始迭代地搜索数组中的每个元素?
答案 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