I often find myself building lookup tables in Ruby, generally to cache some expensive computation or to build something I'm passing to a view. I figure there must be a short, readable idiom for this, but we couldn't think of one. For example, suppose I want to start with
[65, 66, 67, ...]
and end up with
{65 => "A", 66 => "B", 67 => "C", ...}
The not-quite-pretty-enough idioms we could think of include:
array = (65..90).to_a
array.inject({}) {|hash, key| hash[key]=key.chr; hash}
{}.tap {|hash| array.each {|key| hash[key] = key.chr}}
Hash[array.zip(array.map{|key| key.chr})]
But all of these are a little painful: hard to read, easy to mess up, not clear in intent. Surely Ruby (or some Rails helper) has some nice magic for this?
How do you turn an array into a hash in Ruby? The to_h method is defined in the array class. It works to convert an array to a hash in the form of key-value pairs. The method converts each nested array into key-value pairs.
Array#find_index() : find_index() is a Array class method which returns the index of the first array. If a block is given instead of an argument, returns the index of the first object for which the block returns true.
A Hash is a collection of key-value pairs. It is similar to an Array , except that indexing is done via arbitrary keys of any object type, not an integer index.
Hash literals use the curly braces instead of square brackets and the key value pairs are joined by =>. For example, a hash with a single key/value pair of Bob/84 would look like this: { "Bob" => 84 }. Additional key/value pairs can be added to the hash literal by separating them with commas.
I think the most idiomatic way from Ruby 2.1 onwards is to use .to_h
since it can be called on a block like so:
(65..90).map { |i| [i, i.chr] }.to_h
What about
Hash[(65..90).map { |i| [i, i.chr] }]
I think this is quite obvious and self-explaining. Also, I don't there exists a much simpler way to solve this rather specific task, Ruby unfortunately doesn't have something comparable to dict comprehension in Python. If you want, you can use the Facets gem, which includes something close:
require 'facets'
(65..90).mash { |i| [i, i.chr] }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With