2017-07-06 47 views
1

对于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 

但是,按预期它不工作。在我的代码下面,搜索'h [[“a”,“b”]]应该产生“1”,因为第一个元素“a”是我散列中的一个键。

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

你已经差不多了,但问题是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 
相关问题