我想创建一个带有来自数组的索引的哈希。
ary = ["a", "b", "c"]
h = Hash.new(ary.each{|a| h[a] = 0})
我的目标是从这样的哈希开始:
h = {"a"=>0, "b"=>0, "c"=>0}
以便稍后当哈希值发生变化时,我可以使用h.default重置它
不幸的是,我设置哈希的方式不起作用......任何想法?
答案 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}