Kyle Decot
Kyle Decot

Reputation: 20815

Get numeric keys from Hash in Ruby

Say I have a hash like:

h = { '0' => 'foo', 'bar' => 'baz' => '2' => 'yada'  }

How would I go about determining if this hash has any numeric keys in it and pulling out the values of those keys?

Upvotes: 0

Views: 519

Answers (4)

kyoto
kyoto

Reputation: 125

Another solution:

h.select {|k,v| k.to_i.to_s == k}.values

This returns the values for keys that are integers (positive or negative).

Upvotes: 2

Jwosty
Jwosty

Reputation: 3624

Or for a possibly slightly more readable but longer solution, try:

    class String
      def is_i?
        # Returns false if the character is not an integer
        each_char {|c| return false unless /[\d.-]/ =~ c}
        # If we got here, it must be an integer
        true
      end
    end
    h = {"42"=>"mary", "foo"=>"had a", "0"=>"little", "-3"=>"integer"}
    result = []
    h.each {|k, v| result << v if k.is_i?} 

Upvotes: 1

Rachid Al Maach
Rachid Al Maach

Reputation: 181

try this:

h.select {|key| [*0..9].map(&:to_s).include? key }

remember that I didn't pulled out the value for you, it just returns a selection of your hash with the desired criteria. Pulling the values out this hash like you're used to.

Upvotes: 2

mu is too short
mu is too short

Reputation: 434585

If "numeric" means integer then:

a = h.each_with_object([]) { |(k, v), a| a << v if(k.to_i.to_s == k) }

If "numeric" also includes floating point values then:

h.each_with_object([]) { |(k, v), a| a << v if(k =~ /\A[+-]?\d+(\.\d+)?\z/) }

For example:

>> h = { '0' => 'foo', 'bar' => 'baz', '2' => 'yada', '-3.1415927' => 'pancakes' }
=> {"0"=>"foo", "bar"=>"baz", "2"=>"yada", "-3.1415927"=>"pancakes"}
>> h.each_with_object([]) { |(k, v), a| a << v if(k =~ /\A[+-]?\d+(\.\d+)?\z/) }
=> ["foo", "yada", "pancakes"]

You might want to adjust the regex test to allow leading and trailing whitespace (or not).

Upvotes: 1

Related Questions