使用默认密钥创建新哈希

时间:2011-05-06 18:51:14

标签: ruby-on-rails ruby

我想创建一个带有来自数组的索引的哈希。

ary = ["a", "b", "c"]
h = Hash.new(ary.each{|a| h[a] = 0})

我的目标是从这样的哈希开始:

h = {"a"=>0, "b"=>0, "c"=>0}

以便稍后当哈希值发生变化时,我可以使用h.default重置它

不幸的是,我设置哈希的方式不起作用......任何想法?

7 个答案:

答案 0 :(得分:9)

首先应实例化哈希h,然后用数组内容填充它:

h = {}    
ary = ["a", "b", "c"]
ary.each{|a| h[a] = 0}

答案 1 :(得分:5)

使用散列的默认值功能

h = Hash.new(0)

h["a"]      # => 0

在这种方法中,未设置密钥。

h.key?("a") # => false

其他方法是在访问时设置缺失密钥。

h = Hash.new {|h, k| h[k] = 0}
h["a"]      # => 0
h.key?("a") # => true

即使在这种方法中,如果您之前没有访问过密钥,key?之类的操作也会失败。

h.key?("b") # => false
h["b"]      # => 0
h.key?("b") # => true

你可以随时使用具有最小边界条件的蛮力。

h = Hash.new.tap {|h| ["a", "b", "c"].each{|k| h[k] = 0}}
h.key?("b") # => true
h["b"]      # => 0

答案 2 :(得分:3)

你可以这样做,将列表扩展为零初始值:

list = %w[ a b c ]

hash = Hash[list.collect { |i| [ i, 0 ] }]

对于任何给定的密钥,您也可以创建一个默认值为0的哈希:

hash = Hash.new { |h, k| h[k] = 0 }

所引用的任何新密钥都将预先初始化为默认值,这将避免必须初始化整个哈希值。

答案 3 :(得分:2)

这可能不是最有效的方式,但我总是很欣赏能够揭示Ruby多功能性的单行内容:

h =  Hash[['a', 'b', 'c'].collect { |v|  [v, 0] }]

或另一个做同样事情的单行:

h = ['a', 'b', 'c'].inject({}) {|h, v| h[v] = 0; h }

顺便说一下,从性能的角度来看,单线运行速度约为80%:

h = {}
ary = ['a','b','c']
ary.each { |a| h[a]=0 }

答案 4 :(得分:0)

另一个选择是使用Enum#inject方法,因为它的清洁度,我是粉丝。与其他选项相比,我没有对它进行基准测试。

h = ary.inject({}) {|hash, key| hash[key] = 0; hash}

答案 5 :(得分:0)

使用实际添加的键进行哈希的替代方法

Hash[[:a, :b, :c].zip([])] # => {:a=>nil, :b=>nil, :c=>nil}

Hash[[:a, :b, :c].zip(Array.new(3, 0))] # => {:a=>0, :b=>0, :c=>0}

答案 6 :(得分:0)

Rails 6在index_with模块上添加了Enumerable。这将有助于从带有默认值或获取值的枚举数创建哈希。

ary = %w[a b c]
hash = ary.index_with(0) # => {"a"=>0, "b"=>0, "c"=>0}