...
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## get
24
25Given a map and a key, get the value from the map.
26
27```
28get $myDict "key1"
29```
30
31The above returns `"value1"`
32
33Note that if the key is not found, this operation will simply return `""`. No error
34will be generated.
35
36## set
37
38Use `set` to add a new key/value pair to a dictionary.
39
40```
41$_ := set $myDict "name4" "value4"
42```
43
44Note that `set` _returns the dictionary_ (a requirement of Go template functions),
45so you may need to trap the value as done above with the `$_` assignment.
46
47## unset
48
49Given a map and a key, delete the key from the map.
50
51```
52$_ := unset $myDict "name4"
53```
54
55As with `set`, this returns the dictionary.
56
57Note that if the key is not found, this operation will simply return. No error
58will be generated.
59
60## hasKey
61
62The `hasKey` function returns `true` if the given dict contains the given key.
63
64```
65hasKey $myDict "name1"
66```
67
68If the key is not found, this returns `false`.
69
70## pluck
71
72The `pluck` function makes it possible to give one key and multiple maps, and
73get a list of all of the matches:
74
75```
76pluck "name1" $myDict $myOtherDict
77```
78
79The above will return a `list` containing every found value (`[value1 otherValue1]`).
80
81If the give key is _not found_ in a map, that map will not have an item in the
82list (and the length of the returned list will be less than the number of dicts
83in the call to `pluck`.
84
85If the key is _found_ but the value is an empty value, that value will be
86inserted.
87
88A common idiom in Sprig templates is to uses `pluck... | first` to get the first
89matching key out of a collection of dictionaries.
90
91## dig
92
93The `dig` function traverses a nested set of dicts, selecting keys from a list
94of values. It returns a default value if any of the keys are not found at the
95associated dict.
96
97```
98dig "user" "role" "humanName" "guest" $dict
99```
100
101Given a dict structured like
102```
103{
104 user: {
105 role: {
106 humanName: "curator"
107 }
108 }
109}
110```
111
112the above would return `"curator"`. If the dict lacked even a `user` field,
113the result would be `"guest"`.
114
115Dig can be very useful in cases where you'd like to avoid guard clauses,
116especially since Go's template package's `and` doesn't shortcut. For instance
117`and a.maybeNil a.maybeNil.iNeedThis` will always evaluate
118`a.maybeNil.iNeedThis`, and panic if `a` lacks a `maybeNil` field.)
119
120`dig` accepts its dict argument last in order to support pipelining. For instance:
121```
122merge a b c | dig "one" "two" "three" "<missing>"
123```
124
125## merge, mustMerge
126
127Merge two or more dictionaries into one, giving precedence to the dest dictionary:
128
129```
130$newdict := merge $dest $source1 $source2
131```
132
133`mustMerge` will return an error in case of unsuccessful merge.
134
135## mergeOverwrite, mustMergeOverwrite
136
137Merge two or more dictionaries into one, giving precedence from **right to left**, effectively
138overwriting values in the dest dictionary:
139
140Given:
141
142```
143dst:
144 default: default
145 overwrite: me
146 key: true
147
148src:
149 overwrite: overwritten
150 key: false
151```
152
153will result in:
154
155```
156newdict:
157 default: default
158 overwrite: overwritten
159 key: false
160```
161
162```
163$newdict := mergeOverwrite $dest $source1 $source2
164```
165
166`mustMergeOverwrite` will return an error in case of unsuccessful merge.
167
168## keys
169
170The `keys` function will return a `list` of all of the keys in one or more `dict`
171types. Since a dictionary is _unordered_, the keys will not be in a predictable order.
172They can be sorted with `sortAlpha`.
173
174```
175keys $myDict | sortAlpha
176```
177
178When supplying multiple dictionaries, the keys will be concatenated. Use the `uniq`
179function along with `sortAlpha` to get a unqiue, sorted list of keys.
180
181```
182keys $myDict $myOtherDict | uniq | sortAlpha
183```
184
185## pick
186
187The `pick` function selects just the given keys out of a dictionary, creating a
188new `dict`.
189
190```
191$new := pick $myDict "name1" "name2"
192```
193
194The above returns `{name1: value1, name2: value2}`
195
196## omit
197
198The `omit` function is similar to `pick`, except it returns a new `dict` with all
199the keys that _do not_ match the given keys.
200
201```
202$new := omit $myDict "name1" "name3"
203```
204
205The above returns `{name2: value2}`
206
207## values
208
209The `values` function is similar to `keys`, except it returns a new `list` with
210all the values of the source `dict` (only one dictionary is supported).
211
212```
213$vals := values $myDict
214```
215
216The above returns `list["value1", "value2", "value 3"]`. Note that the `values`
217function gives no guarantees about the result ordering- if you care about this,
218then use `sortAlpha`.
219
220## A Note on Dict Internals
221
222A `dict` is implemented in Go as a `map[string]interface{}`. Go developers can
223pass `map[string]interface{}` values into the context to make them available
224to templates as `dict`s.
View as plain text