How to initialize a hash with keys from an array like the following?
keys = [ 'a' , 'b' , 'c' ]
Desired hash h should be:
puts h
# { 'a' => nil , 'b' => nil , 'c' => nil }
How to initialize a hash with keys from an array like the following?
keys = [ 'a' , 'b' , 'c' ]
Desired hash h should be:
puts h
# { 'a' => nil , 'b' => nil , 'c' => nil }
Here we go using Enumerable#each_with_object and Hash::[].
keys = [ 'a' , 'b' , 'c' ]
Hash[keys.each_with_object(nil).to_a]
# => {"a"=>nil, "b"=>nil, "c"=>nil}
or Using Array#product
keys = [ 'a' , 'b' , 'c' ]
Hash[keys.product([nil])]
# => {"a"=>nil, "b"=>nil, "c"=>nil}
[]' from (irb):29 from C:/RailsInstaller/Ruby1.9.3/bin/irb:12:in <main>' >> 'Hash[keys.each_with_object(nil).to_a].Hash.[], not Kernel#Hash, they are quite different methods.puts h # { 'a' => [] , 'b' => [] , 'c' => [] }Hash[ keys.product([ [] ]) ] Will not do what you think! It initializes each member of the hash to the same Array value. Adding a member to one of the arrays adds the same member to all the arrays.Using the new (Ruby 2.1) to_h:
keys.each_with_object(nil).to_h
Another alternative using Array#zip:
Hash[keys.zip([])]
# => {"a"=>nil, "b"=>nil, "c"=>nil}
Update: As suggested by Arup Rakshit here's a performance comparison between the proposed solutions:
require 'fruity'
ary = *(1..10_000)
compare do
each_with_object { ary.each_with_object(nil).to_a }
product { ary.product([nil]) }
zip { ary.zip([]) }
map { ary.map { |k| [k, nil] } }
end
The result:
Running each test once. Test will take about 1 second.
zip is faster than product by 19.999999999999996% ± 1.0%
product is faster than each_with_object by 30.000000000000004% ± 1.0%
each_with_object is similar to map
zip is faster, but for sure each_with_index is more clear and flexible (using zip you can't produce an hash like {'a' => [], 'b' => [], .... My choice would be using product which is the best compromise, IMHO.each_with_index, rather each_with_object.. :)=> keys = [ 'a' , 'b' , 'c' ]
=> Hash[keys.map { |x, z| [x, z] }]
# {"a"=>nil, "b"=>nil, "c"=>nil}
=> Hash[keys.map { |x| [x, nil] }]
# {"a"=>nil, "b"=>nil, "c"=>nil}
=> Hash[keys.map { |x, _| [x, _] }]
# {"a"=>nil, "b"=>nil, "c"=>nil}
keys.map { |k| [k, nil] }?keys.map { |k, _| [k, _] }I think you should try:
x = {}
keys.map { |k, _| x[k.to_s] = _ }
keys.map { |k, _| x[k.to_s] = _ }. Rather keys.each { |k, _| x[k.to_s] = _ } is enough.If you need to initialize the hash with something specific, you could also use Array#zip with Array#cycle:
Hash[keys.zip([''].cycle)]
# => {"a"=>"", "b"=>"", "c"=>""}