Maps in Crystal

Maps are Crystal’s built-in associative data type (sometimes called hashes or dicts in other languages).

To create an empty map, use the built-in Hash class:

m = Hash(String, Int32).new

Set key/value pairs using typical name[key] = val syntax.

m["k1"] = 7
m["k2"] = 13

Printing a map with e.g. puts will show all of its key/value pairs.

puts "map: #{m}"

Get a value for a key with name[key].

v1 = m["k1"]
puts "v1: #{v1}"

If the key doesn’t exist, nil is returned.

v3 = m["k3"]
puts "v3: #{v3}"

The built-in size returns the number of key/value pairs when called on a map.

puts "len: #{m.size}"

The built-in delete removes key/value pairs from a map.

m.delete("k2")
puts "map: #{m}"

To remove all key/value pairs from a map, use the clear method.

m.clear
puts "map: #{m}"

The optional second return value when getting a value from a map indicates if the key was present in the map. This can be used to disambiguate between missing keys and keys with zero values like 0 or "". Here we didn’t need the value itself, so we ignored it with the blank identifier _.

_, prs = m["k2"]
puts "prs: #{prs}"

You can also declare and initialize a new map in the same line with this syntax.

n = {"foo" => 1, "bar" => 2}
puts "map: #{n}"

Crystal doesn’t have a direct equivalent to the maps package in the example, but you can compare maps using the equality operator ==.

n2 = {"foo" => 1, "bar" => 2}
puts "n == n2" if n == n2

Note that maps appear in the form {"k" => "v", "k" => "v"} when printed with puts.

$ crystal run script.cr
map: {"k1" => 7, "k2" => 13}
v1: 7
v3: nil
len: 2
map: {"k1" => 7}
map: {}
prs: false
map: {"foo" => 1, "bar" => 2}
n == n2