我有一个键值对的散列,类似于 -
myhash={'test1' => 'test1', 'test2 => 'test2', ...}
如何在循环中初始化这样的哈希?基本上我需要它从1..50使用相同的测试$ i值,但我无法弄清楚如何在循环中正确初始化它而不是手动执行。 我知道如何单独遍历每个键值对:
myhash.each_pair do |key, value|
但这对init
没有帮助答案 0 :(得分:4)
怎么样:
hash = (1..50).each.with_object({}) do |i, h|
h["test#{i}"] = "test#{i}"
end
如果你想懒洋洋地这样做,你可以做类似下面的事情:
hash = Hash.new { |hash, key| key =~ /^test\d+/ ? hash[key] = key : nil}
p hash["test10"]
#=> "test10"
p hash
#=> {"test10"=>"test10"}
只要在哈希中找不到密钥,就会调用传递给Hash
构造函数的块,我们检查密钥是否遵循某种模式(根据您的需要),并在哈希中创建一个键值对值等于密钥传递。
答案 1 :(得分:4)
(1..50).map { |i| ["test#{i}"] * 2 }.to_h
上面的解决方案比其他两个答案更干,因为"test"
不会重复两次:)
它是BTW,大约快10%(当键和值不同时不会出现这种情况):
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)
或者可以使用eval
:
hash = {}
(1..50).map { |i| eval "hash['test#{i}'] = 'test#{i}'" }
甚至JSON#parse
:
require 'json'
JSON.parse("{" << (1..50).map { |i| %Q|"test#{i}": "test#{i}"| }.join(',') << "}")
答案 2 :(得分:2)
首先,有Array#to_h,它将键值对数组转换为哈希值。
其次,您可以在循环中初始化这样的哈希,只需执行以下操作:
target = {}
1.upto(50) do |i|
target["test_#{i}"] = "test_#{i}"
end
答案 3 :(得分:1)
你也可以这样做:
hash = Hash.new{|h, k| h[k] = k.itself}
(1..50).each{|i| hash["test#{i}"]}
hash # => ...