我想创建一个哈希表,其中的索引来自于一个数组。
ary = ["a", "b", "c"]
h = Hash.new(ary.each{|a| h[a] = 0})
我的目标是从这样的哈希开始:
h = {"a"=>0, "b"=>0, "c"=>0}
这样,当哈希值改变时,我可以通过h.default将其重置。
不幸的是,我设置哈希值的方式不起作用...有什么想法吗?
我想创建一个哈希表,其中的索引来自于一个数组。
ary = ["a", "b", "c"]
h = Hash.new(ary.each{|a| h[a] = 0})
我的目标是从这样的哈希开始:
h = {"a"=>0, "b"=>0, "c"=>0}
这样,当哈希值改变时,我可以通过h.default将其重置。
不幸的是,我设置哈希值的方式不起作用...有什么想法吗?
h
,然后用数组的内容填充它:h = {}
ary = ["a", "b", "c"]
ary.each{|a| h[a] = 0}
h
时,它仍然是nil。这就像说s = s + 4
,这将给你一个NilClass错误。你在原始实现中遇到了什么错误? - McStretch使用哈希的默认值功能
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
list = %w[ a b c ]
hash = Hash[list.collect { |i| [ i, 0 ] }]
hash = Hash.new { |h, k| h[k] = 0 }
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 }
array.inject({}) { |h, v| h.update(v => 0) }
- jsandersary = %w[a b c]
hash = ary.index_with(0) # => {"a"=>0, "b"=>0, "c"=>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}
Enum#inject
方法,因为它很干净。不过,我还没有与其他选项进行基准测试。h = ary.inject({}) {|hash, key| hash[key] = 0; hash}
Hash.new()
(以及Hash.new {}
)不是这样使用的;相反,它为尚未定义的键提供默认值。Hash[]
(裸构造函数,而不是::new
方法)允许您将现有数组转换为哈希表(虽然它也不会接受这样的参数)。 - Ryan Lue