Dictionaries

When you want to store and look up values based on a unique key, then the dictionary type Dict (also called hash, associative collection, or map in other languages) is what you need. It is basically a collection of two-element tuples of the form (key, value). To define a dictionary d1 as a literal value, the following syntax is used:

// code in Chapter 5dicts.jl:
d1 = Dict(1 => 4.2, 2 => 5.3)

It returns Dict{Int64,Float64} with two entries: 2 => 5.3 and 1 => 4.2, so there are two key-value tuples here, (1, 4.2) and (2, 5.3); the key appears before the => symbol and the value appears after it, and the tuples are separated by commas.

To explicitly specify the types, use:

d1 = Dict{Int64,Float64}(1 => 4.2, 2 => 5.3)
If you use the former [] notation to try to define a dictionary, you now get Array{Pairs{}} instead:
d1 = [1 => 4.2, 2 => 5.3]
# 2-element Array{Pair{Int64,Float64},1}:
# 1 => 4.2
# 2 => 5.3

Here are some other examples:

d2 = Dict{Any,Any}("a"=>1, (2,3)=>true)
d3 = Dict(:A => 100, :B => 200)

The Any type is inferred when a common type among the keys or values cannot be detected.

So a Dict can have keys of different types, and the same goes for the values: their type is then indicated as Any. In general, dictionaries that have type {Any, Any} tend to lead to lower performance since the JIT compiler does not know the exact type of the elements. Dictionaries used in performance-critical parts of the code should therefore be explicitly typed. Notice that the (key, value) pairs are not returned (or stored) in the key order.

If the keys are of the Char or String type, you can also use Symbol as the key type, which could be more appropriate since Symbols are immutable, for example:

d3 = Dict{Symbol,Int64}(:A => 100, :B => 200)

Use the bracket notation, with a key as an index, to get the corresponding value: d3[:B] returns 200. However, the key must exist, otherwise we will get an error, d3[:Z], that returns ERROR: KeyError: key not found: :Z. To get around this, use the get method and provide a default value that is returned instead of the error, get(d3, :Z, 999) returns 999.

Here is a dictionary that resembles an object, storing the field names as symbols in the keys:

dmus = [ :first_name => "Louis", :surname => "Armstrong", 
:occupation => "musician", :date_of_birth => "4/8/1901" ]

To test if a key is present in Dict, you can use the function haskey as follows:

  • haskey(d3, :Z) returns false
  • haskey(d3, :B) returns true

Dictionaries are mutable. If we tell Julia to execute d3[:A] = 150, then the value for key :A in d3 has changed to 150. If we do this with a new key, then that tuple is added to the dictionary:

d3[:C] = 300

d3 is now Dict(:A=>150,:B=>200,:C=>300), and it has three elements: length(d3) returns 3.

d4 = Dict() is an empty dictionary of type Any, and you can start populating it in the same way as in the example with d3.

d5 = Dict{Float64, Int64}() is an empty dictionary with key type Float64 and value type Int64. As to be expected, adding keys or values of another type to a typed dictionary is an error. d5["c"] = 6 returns ERROR: MethodError 'convert' has no method matching convert(::Type{Float64}, ::ASCIIString) and d3["CVO"] = 500 returns ERROR: ArgumentError: CVO is not a valid key for type Symbol.

Deleting a key mapping from a collection is also straightforward. delete!(d3, :B) removes (:B, 200) from the dictionary, and returns the collection that contains only :A => 100.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.147.80.100