Ruby regex key search

14,778

Solution 1

I would advise extending Hash with a new method instead of replacing has_key?.

class Hash
  def has_rkey?(search)
    search = Regexp.new(search.to_s) unless search.is_a?(Regexp)
    !!keys.detect{ |key| key =~ search }
  end
end

This will work with strings, symbols or a regexp as arguments.

irb> h = {:test => 1}
 => {:test=>1}  
irb> h.has_rkey?(:te)
 => true 
irb> h.has_rkey?("te")
 => true 
irb> h.has_rkey?(/te/)
 => true 
irb> h.has_rkey?("foo")
 => false 
irb> h.has_rkey?(:foo)
 => false 
irb> h.has_rkey?(/foo/)
 => false 

Solution 2

I think that using any? is a good solution as stated by qqbenq, but I would prefer using it with grep since it's more succinct.

hash.keys.grep(/regexp/).any?

Solution 3

If you are only interested in a yes/no answer, then any? might be a good option:

hash.keys.any? { |key| key.to_s.match(regexp)}

where regexp is a regular expression.

Solution 4

I am not aware of an absolute answer for this question but if I were to write a hacky method for this, I would do this

!!hash.keys.detect{ |k| k.to_s =~ /Your_Regex_here/ }

This will return true when any key matches regex and false otherwise.

Share:
14,778
Mr. Demetrius Michael
Author by

Mr. Demetrius Michael

Add me on facebook: https://www.facebook.com/DemetriusMichael

Updated on June 05, 2022

Comments

  • Mr. Demetrius Michael
    Mr. Demetrius Michael about 2 years

    http://ruby-doc.org/core-1.9.3/Hash.html#method-i-include-3F

    It is possible to convert hash.has_key?(String) to have a regex search capabilities?

  • Kyle
    Kyle almost 12 years
    just a tip, detect will stop as soon as it finds an element where the predicate returns true. This would prevent you from having to iterate over the entire collection and then checking and array with empty?
  • the911s
    the911s almost 9 years
    Be advised that this changes the lookup time complexity of the hash data structure from O(1) to O(n)... which depending on your intended usage may completely obviate the benefit of using a hash.
  • the911s
    the911s almost 9 years
    Follow-up thought: If you have to do this for a large set of data, you should consider building some type of index. For instance, in some databases, you could create an index on a regex dba.stackexchange.com/questions/10694/…
  • Mark Thomas
    Mark Thomas almost 9 years
    any is superior to detect, as it returns a boolean as desired. Note you have a typo: key => keys
  • qqbenq
    qqbenq almost 9 years
    Thanks, the typo is fixed, and yes, the main reason of this - late - answer was to provide a way where you don't have to !! to get a boolean.
  • Tim K.
    Tim K. almost 8 years
    hash.keys.find {...} will return the key name, if needed