Individual values of a hash are read and written using the []
and []=
methods:
my_hash = { length: 4, width: 5 }
my_hash[:length] #=> => 4
my_hash[:height] = 9
my_hash #=> {:length => 4, :width => 5, :height => 9 }
By default, accessing a key which has not been added to the hash returns nil
, meaning it is always safe to attempt to look up a key's value:
my_hash = {}
my_hash[:age] # => nil
Hashes can also contain keys in strings. If you try to access them normally it will just return a nil
, instead you access them by their string keys:
my_hash = { "name" => "user" }
my_hash[:name] # => nil
my_hash["name"] # => user
For situations where keys are expected or required to exist, hashes have a fetch
method which will raise an exception when accessing a key that does not exist:
my_hash = {}
my_hash.fetch(:age) #=> KeyError: key not found: :age
fetch
accepts a default value as its second argument, which is returned if the key has not been previously set:
my_hash = {}
my_hash.fetch(:age, 45) #=> => 45
fetch
can also accept a block which is returned if the key has not been previously set:
my_hash = {}
my_hash.fetch(:age) { 21 } #=> 21
my_hash.fetch(:age) do |k|
puts "Could not find #{k}"
end
#=> Could not find age
Hashes also support a store
method as an alias for []=
:
my_hash = {}
my_hash.store(:age, 45)
my_hash #=> { :age => 45 }
You can also get all values of a hash using the values
method:
my_hash = { length: 4, width: 5 }
my_hash.values #=> [4, 5]
Note: This is only for Ruby 2.3+ #dig
is handy for nested Hash
s. Extracts the nested value specified by the sequence of idx objects by calling dig at each step, returning nil if any intermediate step is nil.
h = { foo: {bar: {baz: 1}}}
h.dig(:foo, :bar, :baz) # => 1
h.dig(:foo, :zot, :xyz) # => nil
g = { foo: [10, 11, 12] }
g.dig(:foo, 1) # => 11