1# Dictionaries and Dict Functions
2
3Sprig provides a key/value storage type called a `dict` (short for "dictionary",
4as in Python). A `dict` is an _unorder_ type.
5
6The key to a dictionary **must be a string**. However, the value can be any
7type, even another `dict` or `list`.
8
9Unlike `list`s, `dict`s are not immutable. The `set` and `unset` functions will
10modify the contents of a dictionary.
11
12## dict
13
14Creating dictionaries is done by calling the `dict` function and passing it a
15list of pairs.
16
17The following creates a dictionary with three items:
18
19```
20$myDict := dict "name1" "value1" "name2" "value2" "name3" "value 3"
21```
22
23## set
24
25Use `set` to add a new key/value pair to a dictionary.
26
27```
28$_ := set $myDict "name4" "value4"
29```
30
31Note that `set` _returns the dictionary_ (a requirement of Go template functions),
32so you may need to trap the value as done above with the `$_` assignment.
33
34## unset
35
36Given a map and a key, delete the key from the map.
37
38```
39$_ := unset $myDict "name4"
40```
41
42As with `set`, this returns the dictionary.
43
44Note that if the key is not found, this operation will simply return. No error
45will be generated.
46
47## hasKey
48
49The `hasKey` function returns `true` if the given dict contains the given key.
50
51```
52hasKey $myDict "name1"
53```
54
55If the key is not found, this returns `false`.
56
57## pluck
58
59The `pluck` function makes it possible to give one key and multiple maps, and
60get a list of all of the matches:
61
62```
63pluck "name1" $myDict $myOtherDict
64```
65
66The above will return a `list` containing every found value (`[value1 otherValue1]`).
67
68If the give key is _not found_ in a map, that map will not have an item in the
69list (and the length of the returned list will be less than the number of dicts
70in the call to `pluck`.
71
72If the key is _found_ but the value is an empty value, that value will be
73inserted.
74
75A common idiom in Sprig templates is to uses `pluck... | first` to get the first
76matching key out of a collection of dictionaries.
77
78## merge
79
80Merge two or more dictionaries into one, giving precedence to the dest dictionary:
81
82```
83$newdict := merge $dest $source1 $source2
84```
85
86This is a deep merge operation.
87
88## mergeOverwrite
89
90Merge two or more dictionaries into one, giving precedence from **right to left**, effectively
91overwriting values in the dest dictionary:
92
93Given:
94
95```
96dst:
97  default: default
98  overwrite: me
99  key: true
100
101src:
102  overwrite: overwritten
103  key: false
104```
105
106will result in:
107
108```
109newdict:
110  default: default
111  overwrite: overwritten
112  key: false
113```
114
115```
116$newdict := mergeOverwrite $dest $source1 $source2
117```
118
119This is a deep merge operation.
120
121## keys
122
123The `keys` function will return a `list` of all of the keys in one or more `dict`
124types. Since a dictionary is _unordered_, the keys will not be in a predictable order.
125They can be sorted with `sortAlpha`.
126
127```
128keys $myDict | sortAlpha
129```
130
131When supplying multiple dictionaries, the keys will be concatenated. Use the `uniq`
132function along with `sortAlpha` to get a unqiue, sorted list of keys.
133
134```
135keys $myDict $myOtherDict | uniq | sortAlpha
136```
137
138## pick
139
140The `pick` function selects just the given keys out of a dictionary, creating a
141new `dict`.
142
143```
144$new := pick $myDict "name1" "name2"
145```
146
147The above returns `{name1: value1, name2: value2}`
148
149## omit
150
151The `omit` function is similar to `pick`, except it returns a new `dict` with all
152the keys that _do not_ match the given keys.
153
154```
155$new := omit $myDict "name1" "name3"
156```
157
158The above returns `{name2: value2}`
159
160## values
161
162The `values` function is similar to `keys`, except it returns a new `list` with
163all the values of the source `dict` (only one dictionary is supported).
164
165```
166$vals := values $myDict
167```
168
169The above returns `list["value1", "value2", "value 3"]`. Note that the `values`
170function gives no guarantees about the result ordering- if you care about this,
171then use `sortAlpha`.
172
173## A Note on Dict Internals
174
175A `dict` is implemented in Go as a `map[string]interface{}`. Go developers can
176pass `map[string]interface{}` values into the context to make them available
177to templates as `dict`s.
178