Ruby - Initialize在循环

时间:2016-01-25 14:34:06

标签: ruby

我有一个键值对的散列,类似于 -

myhash={'test1' => 'test1', 'test2 => 'test2', ...}

如何在循环中初始化这样的哈希?基本上我需要它从1..50使用相同的测试$ i值,但我无法弄清楚如何在循环中正确初始化它而不是手动执行。 我知道如何单独遍历每个键值对:

 myhash.each_pair do |key, value|

但这对init

没有帮助

4 个答案:

答案 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 # => ...