Ken
Ken

Reputation: 1558

How to convert the values of a hash from String to Array in Ruby?

I'm looking to perform a conversion of the values in a Ruby hash from String to Integer.

I thought this would be fairly similar to the way you perform a conversion in a Ruby array (using the map method), but I have not been able to find an elegant solution that doesn't involve converting the hash to an array, flattening it, etc.

Is there a clean solution to do this?

Eg. From

x = { "a" => "1", "b" => "2", "c"=> "3" }

To

x = { "a" => 1, "b" => 2, "c" => 3 }

Upvotes: 2

Views: 396

Answers (4)

sluukkonen
sluukkonen

Reputation: 2616

To avoid modifying the original Hash (unlike the existing answers), I'd use

newhash = x.reduce({}) do |h, (k, v)|
  h[k] = v.to_i and h
end

If you're using Ruby 1.9, you can also use Enumerable#each_with_object to achieve the same effect a bit more cleanly.

newhash = x.each_with_object({}) do |(k, v), h|
  h[k] = v.to_i
end

If you want to, you can also extract the logic into a module and extend the Hash class with it.

module HMap
  def hmap
    self.each_with_object({}) do |(k, v), h|
      h[k] = yield(k, v)
    end
  end
end

class Hash
  include HMap
end

Now you can use

newhash = x.hmap { |k, v| v.to_i } # => {"a"=>1, "b"=>2, "c"=>3}

Upvotes: 4

Michael Kohl
Michael Kohl

Reputation: 66837

My preferred solution:

Hash[x.map { |k, v| [k, v.to_i]}] #=> {"a"=>1, "b"=>2, "c"=>3}

A somewhat wasteful one (has to iterate over the values twice):

Hash[x.keys.zip(x.values.map(&:to_i))] #=> {"a"=>1, "b"=>2, "c"=>3}

Upvotes: 3

Gaurav Shah
Gaurav Shah

Reputation: 5279

p.keys.map { |key| p[key] = p[key].to_i }

Upvotes: 0

Ivaylo Strandjev
Ivaylo Strandjev

Reputation: 70931

Try this:

x.each{|k,v| x[k]=v.to_i}

Upvotes: 2

Related Questions