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