|
| 1 | +# About |
| 2 | + |
| 3 | +## Pairs |
| 4 | + |
| 5 | +A [`Pair`][pair] is just two items joined together. |
| 6 | +The items are then imaginatively called `first` and `second`. |
| 7 | + |
| 8 | +Create them either with the `=>` operator or the `Pair()` constructor. |
| 9 | + |
| 10 | +```julia-repl |
| 11 | +julia> p1 = "k" => 2 |
| 12 | +"k" => 2 |
| 13 | +
|
| 14 | +julia> p2 = Pair("k", 2) |
| 15 | +"k" => 2 |
| 16 | +
|
| 17 | +# Both forms of syntax give the same result |
| 18 | +julia> p1 == p2 |
| 19 | +true |
| 20 | +
|
| 21 | +# Each component has its own separate type |
| 22 | +julia> dump(p1) |
| 23 | +Pair{String, Int64} |
| 24 | + first: String "k" |
| 25 | + second: Int64 2 |
| 26 | +
|
| 27 | +# Get a component using dot syntax |
| 28 | +julia> p1.first |
| 29 | +"k" |
| 30 | +
|
| 31 | +julia> p1.second |
| 32 | +2 |
| 33 | +``` |
| 34 | + |
| 35 | +## Dicts |
| 36 | + |
| 37 | +A `Vector` of Pairs is like any other array: ordered, homogeneous in type, and stored consecutively in memory. |
| 38 | + |
| 39 | +```julia-repl |
| 40 | +julia> pv = ['a' => 1, 'b' => 2, 'c' => 3] |
| 41 | +3-element Vector{Pair{Char, Int64}}: |
| 42 | + 'a' => 1 |
| 43 | + 'b' => 2 |
| 44 | + 'c' => 3 |
| 45 | +
|
| 46 | +# Each pair is a single entry |
| 47 | +julia> length(pv) |
| 48 | +3 |
| 49 | +``` |
| 50 | + |
| 51 | +A [`Dict`][dict] is superficially similar, but storage is now implemented in a way that allows fast retrieval by key, known as a "hash table", even when the number of entries grows large. |
| 52 | + |
| 53 | +```julia-repl |
| 54 | +julia> pd = Dict('a' => 1, 'b' => 2, 'c' => 3) # or Dict(pv) gives same result |
| 55 | +Dict{Char, Int64} with 3 entries: |
| 56 | + 'a' => 1 |
| 57 | + 'c' => 3 |
| 58 | + 'b' => 2 |
| 59 | +
|
| 60 | +julia> pd['b'] |
| 61 | +2 |
| 62 | +
|
| 63 | +# Key must exist |
| 64 | +julia> pd['d'] |
| 65 | +ERROR: KeyError: key 'd' not found |
| 66 | +
|
| 67 | +# Generators are accepted in the constructor (and note the unordered output) |
| 68 | +julia> Dict(x => x^2 for x in 1:5) |
| 69 | +julia> Dict(x => 1 / x for x in 1:5) |
| 70 | +Dict{Int64, Float64} with 5 entries: |
| 71 | + 5 => 0.2 |
| 72 | + 4 => 0.25 |
| 73 | + 2 => 0.5 |
| 74 | + 3 => 0.333333 |
| 75 | + 1 => 1.0 |
| 76 | + ``` |
| 77 | + |
| 78 | +In other languages, something very similar to a `Dict` might be called a dictionary (Python), a Hash (Ruby) or a HashMap (Java). |
| 79 | + |
| 80 | +For Pairs, whether in isolation or in a Vector, there are few constraints on the type of each component. |
| 81 | + |
| 82 | +To be valid in a `Dict`, the `Pair` must be a `key => value` pair, where the `key` is "hashable". |
| 83 | +Most importantly, this means the `key` must be _immutable_, so `Char`, `Int`, `String`, `Symbol`, and `Tuple` are all fine, but `Vector` is not allowed. |
| 84 | + |
| 85 | +If mutable keys are important to you, there is a separate but much less common [`IdDict`][iddict] type that can allow this. |
| 86 | +See the [manual][dict] for several other variants on the `Dict` type. |
| 87 | + |
| 88 | +### Modifying a Dict |
| 89 | + |
| 90 | +Entries can be added, with a new key, or overwritten, with an existing key. |
| 91 | + |
| 92 | +```julia-repl |
| 93 | +julia> pd |
| 94 | +Dict{Char, Int64} with 3 entries: |
| 95 | + 'a' => 1 |
| 96 | + 'c' => 3 |
| 97 | + 'b' => 2 |
| 98 | +
|
| 99 | +# Add |
| 100 | +julia> pd['d'] = 4 |
| 101 | +4 |
| 102 | +
|
| 103 | +# Overwrite |
| 104 | +julia> pd['a'] = 42 |
| 105 | +42 |
| 106 | +
|
| 107 | +julia> pd |
| 108 | +Dict{Char, Int64} with 4 entries: |
| 109 | + 'a' => 42 |
| 110 | + 'c' => 3 |
| 111 | + 'd' => 4 |
| 112 | + 'b' => 2 |
| 113 | +``` |
| 114 | + |
| 115 | +To remove an entry, use the `delete!()` function, which will change the Dict if the key exists and silently do nothing otherwise. |
| 116 | + |
| 117 | +```julia-repl |
| 118 | +julia> delete!(pd, 'd') |
| 119 | +Dict{Char, Int64} with 3 entries: |
| 120 | + 'a' => 42 |
| 121 | + 'c' => 3 |
| 122 | + 'b' => 2 |
| 123 | +``` |
| 124 | + |
| 125 | +### Checking if a key or value exists |
| 126 | + |
| 127 | +There are different approaches. |
| 128 | +To check a key, there is a `haskey()` function: |
| 129 | + |
| 130 | +```julia-repl |
| 131 | +julia> haskey(pd, 'b') |
| 132 | +true |
| 133 | +``` |
| 134 | + |
| 135 | +Alternatively, search either the keys or the values: |
| 136 | + |
| 137 | +```julia-repl |
| 138 | +julia> 'b' in keys(pd) |
| 139 | +true |
| 140 | +
|
| 141 | +julia> 43 in values(pd) |
| 142 | +false |
| 143 | +
|
| 144 | +julia> 42 ∈ values(pd) |
| 145 | +true |
| 146 | +``` |
| 147 | + |
| 148 | +This remains efficient at scale, as the `keys()` and `values()` functions each return an iterator with a fast search algorithm. |
| 149 | + |
| 150 | + |
| 151 | +[pair]: https://docs.julialang.org/en/v1/base/collections/#Core.Pair |
| 152 | +[dict]: https://docs.julialang.org/en/v1/base/collections/#Dictionaries |
| 153 | +[iddict]: https://docs.julialang.org/en/v1/base/collections/#Base.IdDict |
0 commit comments