5

I want to convert:

[:one, :two, :three]

to:

{one: :one, two: :two, three: :three}

So far I'm using this:

Hash[[:basic, :silver, :gold, :platinum].map { |e| [e, e] }]

But I would like to know if it's possible by some other way?

This is to use in a Rails enum definition in model, to save values as strings in db.

mechnicov
  • 12,025
  • 4
  • 33
  • 56
Arnold Roa
  • 7,335
  • 5
  • 50
  • 69

4 Answers4

6

Array#zip:

a = [:one, :two, :three]
a.zip(a).to_h
#=> {:one=>:one, :two=>:two, :three=>:three}

Array#transpose:

[a, a].transpose.to_h
#=> {:one=>:one, :two=>:two, :three=>:three}
Andrey Deineko
  • 51,333
  • 10
  • 112
  • 145
3

I prefer constructing hashes from scratch rather than constructing a temporary array (which consumes memory) and converting it to a hash.

[:one, :two, :three].each_with_object({}) { |e,h| h[e]=e }
  #=> {:one=>:one, :two=>:two, :three=>:three}
Cary Swoveland
  • 106,649
  • 6
  • 63
  • 100
  • totally agree with creating hash from scratch, I usually resort to `each_with_object` in such cases, but `a.zip(a).to_h` is so much less typing :D – Andrey Deineko Nov 14 '16 at 12:08
2

In Ruby on Rails 6+ it is possible to use Enumerable#index_with

If combine it with Object#itself, it will look such way:

%i[one two three].index_with(&:itself)

# => {:one=>:one, :two=>:two, :three=>:three}

And yes, it is convenient to use enum to declare strings stored in the database with hash such way

enum my_attribute: MY_ARRAY.index_with(&:itself)
mechnicov
  • 12,025
  • 4
  • 33
  • 56
1

Here is another way with map:

>> [:one, :two, :three].map { |x| [x,x] }.to_h
=> {:one=>:one, :two=>:two, :three=>:three}
Roman Kiselenko
  • 43,210
  • 9
  • 91
  • 103