Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to initialize a hash with keys from an array?

Tags:

ruby

hash

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 }
like image 411
user3206440 Avatar asked Jan 17 '14 13:01

user3206440


People also ask

How do you initialize a hash?

Another initialization method is to pass Hash. new a block, which is invoked each time a value is requested for a key that has no value. This allows you to use a distinct value for each key. The block is passed two arguments: the hash being asked for a value, and the key used.

How do I initialize a hash in Perl?

Regular way of initializing a hash : my %h1=("Jan" => 31, "Feb" => 28, "Mar" => 31); This is the normal way of populating hash where-in every set is a key-value pair. The operator separating the key-value pair '=>' is called Fat-comma operator.

How do I declare an array of hash in Perl?

A Perl hash is defined by key-value pairs. Perl stores elements of a hash in such an optimal way that you can look up its values based on keys very fast. Like a scalar or an array variable, a hash variable has its own prefix. A hash variable must begin with a percent sign (%).


4 Answers

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}
like image 33
Arup Rakshit Avatar answered Oct 16 '22 18:10

Arup Rakshit


Using the new (Ruby 2.1) to_h:

keys.each_with_object(nil).to_h
like image 151
steenslag Avatar answered Oct 16 '22 18:10

steenslag


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
like image 29
toro2k Avatar answered Oct 16 '22 18:10

toro2k


=> 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}
like image 42
Philidor Avatar answered Oct 16 '22 18:10

Philidor