Take the 2-minute tour ×

What is the simplest way to convert the range 1..10 into a hash of the following format?

  1 => '£1',
  2 => '£2',
  # ...

I have tried doing this with map, but end up with an array of hashes rather than a single hash.


share|improve this question
add comment

3 Answers

up vote 11 down vote accepted
Hash[(1..10).map { |num| [num, "£#{num}"] }]


(1..10).inject({}) { |hash, num| hash[num] = "£#{num}"; hash }

or in Ruby 1.9

(1..10).each_with_object({}) { |num, hash| hash[num] = "£#{num}" } 
share|improve this answer
Methods like each_with_object remind me how much I love Ruby! +1 –  ream88 Aug 11 '11 at 12:23
Perfect, thank you! –  gjb Aug 11 '11 at 12:56
needs to SWITCH the |hash, num| to |num, hash| in that last example... else get NoMethodError: undefined method `[]=' for 1:Fixnum –  jpwynn Jun 17 '13 at 22:01
@jpwynn..yes..you are right. The order is reverse. will update it in the answer. –  rubyprince Jun 18 '13 at 7:00
add comment

How about:

h = {}
(1..10).each {|x| h[x] = "£#{x}"}
share|improve this answer
Simple rule of thumb - every time you declare an empty value (hash or array) and then iterate over collection to fill/sum it - use inject –  iafonov Aug 11 '11 at 12:19
@iafonov..for array, you can use map. –  rubyprince Aug 11 '11 at 12:47
@iafonov I realise this is an old post, but I saw your comment (and I'm new to Ruby), and it just left me wondering why you should use inject. I'm not saying it's wrong or anything, I'd just like to understand the reasons behind it as the each approach above is easy to read and understand - and as I understand it, does the job. –  Thor84no Nov 14 '12 at 13:27
add comment

another way

h = Hash.new { |hash, key| hash[key] = "£#{key}" }

each element will have appropriate value hovever it will also respond to h[100] what might cause bugs

share|improve this answer
add comment

Your Answer


