Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby array to an indexed hash?

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?

like image 227
William Pietri Avatar asked Feb 28 '12 01:02

William Pietri


People also ask

How do you turn an array into a hash in Ruby?

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.

How do you return an index of an element in an array in Ruby?

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.

Are hashes indexed Ruby?

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.

How do you add something to a hash in Ruby?

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.


2 Answers

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
like image 137
jarv Avatar answered Oct 16 '22 13:10

jarv


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] }
like image 38
Niklas B. Avatar answered Oct 16 '22 14:10

Niklas B.