Reputation: 113
I have a hash of key value pairs, similar to -
myhash={'test1' => 'test1', 'test2 => 'test2', ...}
how can I initialize such a hash in a loop? Basically I need it to go from 1..50 with the same test$i values but I cannot figure out how to initialize it properly in a loop instead of doing it manually. I know how to loop through each key-value pair individually:
myhash.each_pair do |key, value|
but that doesn't help with init
Upvotes: 0
Views: 730
Reputation: 121000
(1..50).map { |i| ["test#{i}"] * 2 }.to_h
The solution above is more DRY than two other answers, since "test"
is not repeated twice :)
It is BTW, approx 10% faster (that would not be a case when keys and values differ):
require 'benchmark'
n = 500000
Benchmark.bm do |x|
x.report { n.times do ; (1..50).map { |i| ["test#{i}"] * 2 }.to_h ; end }
x.report { n.times do ; (1..50).each.with_object({}) do |i, h| ; h["test#{i}"] = "test#{i}" ; end ; end }
end
user system total real
17.630000 0.000000 17.630000 ( 17.631221)
19.380000 0.000000 19.380000 ( 19.372783)
Or one might use eval
:
hash = {}
(1..50).map { |i| eval "hash['test#{i}'] = 'test#{i}'" }
or even JSON#parse
:
require 'json'
JSON.parse("{" << (1..50).map { |i| %Q|"test#{i}": "test#{i}"| }.join(',') << "}")
Upvotes: 4
Reputation: 18762
How about:
hash = (1..50).each.with_object({}) do |i, h|
h["test#{i}"] = "test#{i}"
end
If you want to do this lazily, you could do something like below:
hash = Hash.new { |hash, key| key =~ /^test\d+/ ? hash[key] = key : nil}
p hash["test10"]
#=> "test10"
p hash
#=> {"test10"=>"test10"}
The block passed to Hash
constructor will be invoked whenever a key is not found in hash, we check whether key follows a certain pattern (based on your need), and create a key-value pair in hash where value is equal to key passed.
Upvotes: 4
Reputation: 168199
You can also do this:
hash = Hash.new{|h, k| h[k] = k.itself}
(1..50).each{|i| hash["test#{i}"]}
hash # => ...
Upvotes: 1
Reputation: 4755
First of all, there's Array#to_h, which converts an array of key-value pairs into a hash.
Second, you can just initialize such a hash in a loop, just do something like this:
target = {}
1.upto(50) do |i|
target["test_#{i}"] = "test_#{i}"
end
Upvotes: 2