2017-07-06 114 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 
相關問題