Paul Holden
Paul Holden

Reputation: 868

Better way for array to hash conversion

I have an array and I want to convert it to a hash. I want the array elements to be keys, and all values to be the same.

Here is my code:

h = Hash.new
myarr.each do |elem|
  h[elem] = 1
end

One alternative would be the following. I don't think it's very different from the solution above.

h = Hash[ *myarr.collect { |elem| [elem, 1] }.flatten ]

Is there a better way I can do this?

Upvotes: 1

Views: 144

Answers (5)

mu is too short
mu is too short

Reputation: 434645

First of all, Hash[] is quite happy to get an array-of-arrays so you can toss out the splat and flatten and just say this:

h = Hash[myarr.map { |e| [ e, 1 ] }]

I suppose you could use each_with_object instead:

h = myarr.each_with_object({}) { |e, h| h[e] = 1 }

Another option would be to zip your myarr with an appropriate array of 1s and then feed that to Hash[]:

h = Hash[myarr.zip([1] * myarr.length)]

I'd probably use the first one though.

Upvotes: 3

Mark Thomas
Mark Thomas

Reputation: 37517

If you are using Ruby 2.1:

myarr.map{|e| [e,1]}.to_h

Another clever way (from comment by @ArupRakshit):

myarr.product([1]).to_h

Upvotes: 3

Uri Agassi
Uri Agassi

Reputation: 37409

Here is another option, using cycle:

Hash[a.zip([1].cycle)]

Upvotes: 1

Arup Rakshit
Arup Rakshit

Reputation: 118271

The code OP wrote, can also be written as :-

a = %w(a b c d)
Hash[a.each_with_object(1).to_a]
# => {"a"=>1, "b"=>1, "c"=>1, "d"=>1}

And if you have Ruby version >= 2.1, then

a.each_with_object(1).to_h
# => {"a"=>1, "b"=>1, "c"=>1, "d"=>1}

Upvotes: 6

sawa
sawa

Reputation: 168091

a.each_with_object({}){|e, h| h[e] = 1}

Upvotes: -1

Related Questions