設定預設值
預設情況下,嘗試查詢不存在的鍵的值將返回 nil
。當使用不存在的金鑰訪問雜湊時,你可以選擇指定要返回的其他值(或要採取的操作)。雖然這被稱為預設值,但它不必是單個值; 例如,它可以是計算值,例如金鑰的長度。
雜湊的預設值可以傳遞給它的建構函式:
h = Hash.new(0)
h[:hi] = 1
puts h[:hi] # => 1
puts h[:bye] # => 0 returns default value instead of nil
也可以在已構造的雜湊上指定預設值:
my_hash = { human: 2, animal: 1 }
my_hash.default = 0
my_hash[:plant] # => 0
請務必注意,每次訪問新金鑰時都不會複製預設值,這可能會在預設值為引用型別時導致令人驚訝的結果:
# Use an empty array as the default value
authors = Hash.new([])
# Append a book title
authors[:homer] << 'The Odyssey'
# All new keys map to a reference to the same array:
authors[:plato] # => ['The Odyssey']
為避免此問題,Hash 建構函式接受每次訪問新金鑰時執行的塊,並將返回的值用作預設值:
authors = Hash.new { [] }
# Note that we're using += instead of <<, see below
authors[:homer] += ['The Odyssey']
authors[:plato] # => []
authors # => {:homer=>["The Odyssey"]}
注意,上面我們必須使用+ =而不是<<因為預設值不會自動分配給雜湊值; 使用<<會新增到陣列中,但作者[:homer]將保持未定義:
authors[:homer] << 'The Odyssey' # ['The Odyssey']
authors[:homer] # => []
authors # => {}
為了能夠在訪問時分配預設值,以及計算更復雜的預設值,預設塊將傳遞雜湊和金鑰:
authors = Hash.new { |hash, key| hash[key] = [] }
authors[:homer] << 'The Odyssey'
authors[:plato] # => []
authors # => {:homer=>["The Odyssey"], :plato=>[]}
你還可以使用預設塊來執行操作和/或返回取決於鍵(或其他一些資料)的值:
chars = Hash.new { |hash,key| key.length }
chars[:test] # => 4
你甚至可以建立更復雜的雜湊:
page_views = Hash.new { |hash, key| hash[key] = { count: 0, url: key } }
page_views["http://example.com"][:count] += 1
page_views # => {"http://example.com"=>{:count=>1, :url=>"http://example.com"}}
要在已存在的雜湊上將預設值設定為 Proc,請使用 default_proc=
:
authors = {}
authors.default_proc = proc { [] }
authors[:homer] += ['The Odyssey']
authors[:plato] # => []
authors # {:homer=>["The Odyssey"]}