Hashes

Hashes are the ideal container type for dealing with key/value pairs.

Creating a hash is simple. In the following example, we'll be creating a Hash with the type Hash(String, Int32)

friends_age = {
  "John"   => 42,
  "Jane"   => 31,
  "George" => 50,
  "Max"    => 28,
}

p typeof(friends_age) # => Hash(String, Int32)

Accessing values

You can read a value using keys:

p friends_age["Jane"] # => 31

Trying to acces a value which doesn't exist will result in an exception:

p friends_age["Patrick"] # => Error: Unhandled exception, missing hash key "Patrick"

Therefore, we need to handle the outcome where a key might not exist with ?:

p friends_age["Jane"]?    # => 31
p friends_age["Patrick"]?  # => nil

Another way to handle this would be to use the predicate function has_key?

p friends_age.has_key? "Jane"     # => true
p friends_age.has_key? "Patrick"  # => false

Updating Values

We can update a value quite simply:

friends["John"] = 43

Creating Hashes

Just like arrays, declaring an empty hash with no values and no type information is not possible:

my_hash = {}  # => Error: for empty hashes use {} of KeyType => ValueType

Instead we need to provide the type information:

my_hash = {} of String => Int32
my_hash_two = Hash(String, Int32).new

If you want to check if the hash is empty, you can use the empty? predicate:

p my_hash.empty? # => false

Examples of Different Syntax

There are different ways to declare key value pairs, have a look at the following declarations and their inferred types:

hash_a = {"a" => 1, "b" => 2, "c" => 3} # => Hash(String, Int32)
hash_b = {:a => 1, :b => 2, :c => 3}    # => Hash(Symbol, Int32)
hash_b2 = {a: 1, b: 2, c: 3}            # => NamedTuple(a: Int32, b: Int32, c: Int32)
hash_c = {"a": 1, "b": 2, "c": 3}       # => NamedTuple(a: Int32, b: Int32, c: Int32)

If a hash uses symbols as keys, you can access them like so:

fruits = {:watermelon => 4.99, :banana => 2.00}

p fruits[:watermelon]   # => 4.99
p "Keys: #{fruits.keys} Values: #{fruits.values}" # => "Key: [:watermelon, :banana] Value: [4.99, 2.0]"