1dict(n) Tcl Built-In Commands dict(n)
2
3
4
5______________________________________________________________________________
6
8 dict - Manipulate dictionaries
9
11 dict option arg ?arg ...?
12______________________________________________________________________________
13
15 Performs one of several operations on dictionary values or variables
16 containing dictionary values (see the DICTIONARY VALUES section below
17 for a description), depending on option. The legal options (which may
18 be abbreviated) are:
19
20 dict append dictionaryVariable key ?string ...?
21 This appends the given string (or strings) to the value that the
22 given key maps to in the dictionary value contained in the given
23 variable, writing the resulting dictionary value back to that
24 variable. Non-existent keys are treated as if they map to an
25 empty string. The updated dictionary value is returned.
26
27 dict create ?key value ...?
28 Return a new dictionary that contains each of the key/value map‐
29 pings listed as arguments (keys and values alternating, with
30 each key being followed by its associated value.)
31
32 dict exists dictionaryValue key ?key ...?
33 This returns a boolean value indicating whether the given key
34 (or path of keys through a set of nested dictionaries) exists in
35 the given dictionary value. This returns a true value exactly
36 when dict get on that path will succeed.
37
38 dict filter dictionaryValue filterType arg ?arg ...?
39 This takes a dictionary value and returns a new dictionary that
40 contains just those key/value pairs that match the specified
41 filter type (which may be abbreviated.) Supported filter types
42 are:
43
44 dict filter dictionaryValue key ?globPattern ...?
45 The key rule only matches those key/value pairs whose │
46 keys match any of the given patterns (in the style of │
47 string match.)
48
49 dict filter dictionaryValue script {keyVariable valueVariable}
50 script
51 The script rule tests for matching by assigning the key
52 to the keyVariable and the value to the valueVariable,
53 and then evaluating the given script which should return
54 a boolean value (with the key/value pair only being
55 included in the result of the dict filter when a true
56 value is returned.) Note that the first argument after
57 the rule selection word is a two-element list. If the
58 script returns with a condition of TCL_BREAK, no further
59 key/value pairs are considered for inclusion in the
60 resulting dictionary, and a condition of TCL_CONTINUE is
61 equivalent to a false result. The key/value pairs are
62 tested in the order in which the keys were inserted into
63 the dictionary.
64
65 dict filter dictionaryValue value ?globPattern ...?
66 The value rule only matches those key/value pairs whose │
67 values match any of the given patterns (in the style of │
68 string match.)
69
70 dict for {keyVariable valueVariable} dictionaryValue body
71 This command takes three arguments, the first a two-element list
72 of variable names (for the key and value respectively of each
73 mapping in the dictionary), the second the dictionary value to
74 iterate across, and the third a script to be evaluated for each
75 mapping with the key and value variables set appropriately (in
76 the manner of foreach.) The result of the command is an empty
77 string. If any evaluation of the body generates a TCL_BREAK
78 result, no further pairs from the dictionary will be iterated
79 over and the dict for command will terminate successfully imme‐
80 diately. If any evaluation of the body generates a TCL_CONTINUE
81 result, this shall be treated exactly like a normal TCL_OK
82 result. The order of iteration is the order in which the keys
83 were inserted into the dictionary.
84
85 dict get dictionaryValue ?key ...?
86 Given a dictionary value (first argument) and a key (second
87 argument), this will retrieve the value for that key. Where sev‐
88 eral keys are supplied, the behaviour of the command shall be as
89 if the result of dict get $dictVal $key was passed as the first
90 argument to dict get with the remaining arguments as second (and
91 possibly subsequent) arguments. This facilitates lookups in
92 nested dictionaries. For example, the following two commands are
93 equivalent:
94
95 dict get $dict foo bar spong
96 dict get [dict get [dict get $dict foo] bar] spong
97
98 If no keys are provided, dict get will return a list containing
99 pairs of elements in a manner similar to array get. That is, the
100 first element of each pair would be the key and the second ele‐
101 ment would be the value for that key.
102
103 It is an error to attempt to retrieve a value for a key that is
104 not present in the dictionary.
105
106 dict incr dictionaryVariable key ?increment?
107 This adds the given increment value (an integer that defaults to
108 1 if not specified) to the value that the given key maps to in
109 the dictionary value contained in the given variable, writing
110 the resulting dictionary value back to that variable. Non-exis‐
111 tent keys are treated as if they map to 0. It is an error to
112 increment a value for an existing key if that value is not an
113 integer. The updated dictionary value is returned.
114
115 dict info dictionaryValue
116 This returns information (intended for display to people) about
117 the given dictionary though the format of this data is dependent
118 on the implementation of the dictionary. For dictionaries that
119 are implemented by hash tables, it is expected that this will
120 return the string produced by Tcl_HashStats, similar to array
121 statistics.
122
123 dict keys dictionaryValue ?globPattern?
124 Return a list of all keys in the given dictionary value. If a
125 pattern is supplied, only those keys that match it (according to
126 the rules of string match) will be returned. The returned keys
127 will be in the order that they were inserted into the dictio‐
128 nary.
129
130 dict lappend dictionaryVariable key ?value ...?
131 This appends the given items to the list value that the given
132 key maps to in the dictionary value contained in the given vari‐
133 able, writing the resulting dictionary value back to that vari‐
134 able. Non-existent keys are treated as if they map to an empty
135 list, and it is legal for there to be no items to append to the
136 list. It is an error for the value that the key maps to to not
137 be representable as a list. The updated dictionary value is
138 returned.
139
140 dict map {keyVariable valueVariable} dictionaryValue body
141 This command applies a transformation to each element of a dic‐
142 tionary, returning a new dictionary. It takes three arguments:
143 the first is a two-element list of variable names (for the key
144 and value respectively of each mapping in the dictionary), the
145 second the dictionary value to iterate across, and the third a
146 script to be evaluated for each mapping with the key and value
147 variables set appropriately (in the manner of lmap). In an iter‐
148 ation where the evaluated script completes normally (TCL_OK, as
149 opposed to an error, etc.) the result of the script is put into
150 an accumulator dictionary using the key that is the current con‐
151 tents of the keyVariable variable at that point. The result of
152 the dict map command is the accumulator dictionary after all
153 keys have been iterated over.
154
155 If the evaluation of the body for any particular step generates
156 a break, no further pairs from the dictionary will be iterated
157 over and the dict map command will terminate successfully imme‐
158 diately. If the evaluation of the body for a particular step
159 generates a continue result, the current iteration is aborted
160 and the accumulator dictionary is not modified. The order of
161 iteration is the natural order of the dictionary (typically the
162 order in which the keys were added to the dictionary; the order
163 is the same as that used in dict for).
164
165 dict merge ?dictionaryValue ...?
166 Return a dictionary that contains the contents of each of the
167 dictionaryValue arguments. Where two (or more) dictionaries
168 contain a mapping for the same key, the resulting dictionary
169 maps that key to the value according to the last dictionary on
170 the command line containing a mapping for that key.
171
172 dict remove dictionaryValue ?key ...?
173 Return a new dictionary that is a copy of an old one passed in
174 as first argument except without mappings for each of the keys
175 listed. It is legal for there to be no keys to remove, and it
176 also legal for any of the keys to be removed to not be present
177 in the input dictionary in the first place.
178
179 dict replace dictionaryValue ?key value ...?
180 Return a new dictionary that is a copy of an old one passed in
181 as first argument except with some values different or some
182 extra key/value pairs added. It is legal for this command to be
183 called with no key/value pairs, but illegal for this command to
184 be called with a key but no value.
185
186 dict set dictionaryVariable key ?key ...? value
187 This operation takes the name of a variable containing a dictio‐
188 nary value and places an updated dictionary value in that vari‐
189 able containing a mapping from the given key to the given value.
190 When multiple keys are present, this operation creates or
191 updates a chain of nested dictionaries. The updated dictionary
192 value is returned.
193
194 dict size dictionaryValue
195 Return the number of key/value mappings in the given dictionary
196 value.
197
198 dict unset dictionaryVariable key ?key ...?
199 This operation (the companion to dict set) takes the name of a
200 variable containing a dictionary value and places an updated
201 dictionary value in that variable that does not contain a map‐
202 ping for the given key. Where multiple keys are present, this
203 describes a path through nested dictionaries to the mapping to
204 remove. At least one key must be specified, but the last key on
205 the key-path need not exist. All other components on the path
206 must exist. The updated dictionary value is returned.
207
208 dict update dictionaryVariable key varName ?key varName ...? body
209 Execute the Tcl script in body with the value for each key (as
210 found by reading the dictionary value in dictionaryVariable)
211 mapped to the variable varName. There may be multiple key/var‐
212 Name pairs. If a key does not have a mapping, that corresponds
213 to an unset varName. When body terminates, any changes made to
214 the varNames is reflected back to the dictionary within dictio‐
215 naryVariable (unless dictionaryVariable itself becomes unread‐
216 able, when all updates are silently discarded), even if the
217 result of body is an error or some other kind of exceptional
218 exit. The result of dict update is (unless some kind of error
219 occurs) the result of the evaluation of body.
220
221 Each varName is mapped in the scope enclosing the dict update;
222 it is recommended that this command only be used in a local
223 scope (procedure, lambda term for apply, or method). Because of
224 this, the variables set by dict update will continue to exist
225 after the command finishes (unless explicitly unset). Note that
226 the mapping of values to variables does not use traces; changes
227 to the dictionaryVariable's contents only happen when body ter‐
228 minates.
229
230 dict values dictionaryValue ?globPattern?
231 Return a list of all values in the given dictionary value. If a
232 pattern is supplied, only those values that match it (according
233 to the rules of string match) will be returned. The returned
234 values will be in the order of that the keys associated with
235 those values were inserted into the dictionary.
236
237 dict with dictionaryVariable ?key ...? body
238 Execute the Tcl script in body with the value for each key in
239 dictionaryVariable mapped (in a manner similarly to dict update)
240 to a variable with the same name. Where one or more keys are
241 available, these indicate a chain of nested dictionaries, with
242 the innermost dictionary being the one opened out for the execu‐
243 tion of body. As with dict update, making dictionaryVariable
244 unreadable will make the updates to the dictionary be discarded,
245 and this also happens if the contents of dictionaryVariable are
246 adjusted so that the chain of dictionaries no longer exists. The
247 result of dict with is (unless some kind of error occurs) the
248 result of the evaluation of body.
249
250 The variables are mapped in the scope enclosing the dict with;
251 it is recommended that this command only be used in a local
252 scope (procedure, lambda term for apply, or method). Because of
253 this, the variables set by dict with will continue to exist
254 after the command finishes (unless explicitly unset). Note that
255 the mapping of values to variables does not use traces; changes
256 to the dictionaryVariable's contents only happen when body ter‐
257 minates.
258
259 If the dictionaryVariable contains a value that is not a dictio‐
260 nary at the point when the body terminates (which can easily
261 happen if the name is the same as any of the keys in dictionary)
262 then an error occurs at that point. This command is thus not
263 recommended for use when the keys in the dictionary are expected
264 to clash with the dictionaryVariable name itself. Where the con‐
265 tained key does map to a dictionary, the net effect is to com‐
266 bine that inner dictionary into the outer dictionary; see the
267 EXAMPLES below for an illustration of this.
268
270 Dictionaries are values that contain an efficient, order-preserving
271 mapping from arbitrary keys to arbitrary values. Each key in the dic‐
272 tionary maps to a single value. They have a textual format that is
273 exactly that of any list with an even number of elements, with each
274 mapping in the dictionary being represented as two items in the list.
275 When a command takes a dictionary and produces a new dictionary based
276 on it (either returning it or writing it back into the variable that
277 the starting dictionary was read from) the new dictionary will have the
278 same order of keys, modulo any deleted keys and with new keys added on
279 to the end. When a string is interpreted as a dictionary and it would
280 otherwise have duplicate keys, only the last value for a particular key
281 is used; the others are ignored, meaning that, “apple banana” and
282 “apple carrot apple banana” are equivalent dictionaries (with different
283 string representations).
284
285 Operations that derive a new dictionary from an old one (e.g., updates
286 like dict set and dict unset) preserve the order of keys in the dictio‐
287 nary. The exceptions to this are for any new keys they add, which are
288 appended to the sequence, and any keys that are removed, which are
289 excised from the order.
290
292 Basic dictionary usage:
293
294 # Make a dictionary to map extensions to descriptions
295 set filetypes [dict create .txt "Text File" .tcl "Tcl File"]
296
297 # Add/update the dictionary
298 dict set filetypes .tcl "Tcl Script"
299 dict set filetypes .tm "Tcl Module"
300 dict set filetypes .gif "GIF Image"
301 dict set filetypes .png "PNG Image"
302
303 # Simple read from the dictionary
304 set ext ".tcl"
305 set desc [dict get $filetypes $ext]
306 puts "$ext is for a $desc"
307
308 # Somewhat more complex, with existence test
309 foreach filename [glob *] {
310 set ext [file extension $filename]
311 if {[dict exists $filetypes $ext]} {
312 puts "$filename is a [dict get $filetypes $ext]"
313 }
314 }
315
316 Constructing and using nested dictionaries:
317
318 # Data for one employee
319 dict set employeeInfo 12345-A forenames "Joe"
320 dict set employeeInfo 12345-A surname "Schmoe"
321 dict set employeeInfo 12345-A street "147 Short Street"
322 dict set employeeInfo 12345-A city "Springfield"
323 dict set employeeInfo 12345-A phone "555-1234"
324 # Data for another employee
325 dict set employeeInfo 98372-J forenames "Anne"
326 dict set employeeInfo 98372-J surname "Other"
327 dict set employeeInfo 98372-J street "32995 Oakdale Way"
328 dict set employeeInfo 98372-J city "Springfield"
329 dict set employeeInfo 98372-J phone "555-8765"
330 # The above data probably ought to come from a database...
331
332 # Print out some employee info
333 set i 0
334 puts "There are [dict size $employeeInfo] employees"
335 dict for {id info} $employeeInfo {
336 puts "Employee #[incr i]: $id"
337 dict with info {
338 puts " Name: $forenames $surname"
339 puts " Address: $street, $city"
340 puts " Telephone: $phone"
341 }
342 }
343 # Another way to iterate and pick out names...
344 foreach id [dict keys $employeeInfo] {
345 puts "Hello, [dict get $employeeInfo $id forenames]!"
346 }
347
348 A localizable version of string toupper:
349
350 # Set up the basic C locale
351 set capital [dict create C [dict create]]
352 foreach c [split {abcdefghijklmnopqrstuvwxyz} ""] {
353 dict set capital C $c [string toupper $c]
354 }
355
356 # English locales can luckily share the "C" locale
357 dict set capital en [dict get $capital C]
358 dict set capital en_US [dict get $capital C]
359 dict set capital en_GB [dict get $capital C]
360
361 # ... and so on for other supported languages ...
362
363 # Now get the mapping for the current locale and use it.
364 set upperCaseMap [dict get $capital $env(LANG)]
365 set upperCase [string map $upperCaseMap $string]
366
367 Showing the detail of dict with:
368
369 proc sumDictionary {varName} {
370 upvar 1 $varName vbl
371 foreach key [dict keys $vbl] {
372 # Manufacture an entry in the subdictionary
373 dict set vbl $key total 0
374 # Add the values and remove the old
375 dict with vbl $key {
376 set total [expr {$x + $y + $z}]
377 unset x y z
378 }
379 }
380 puts "last total was $total, for key $key"
381 }
382
383 set myDict {
384 a {x 1 y 2 z 3}
385 b {x 6 y 5 z 4}
386 }
387
388 sumDictionary myDict
389 # prints: last total was 15, for key b
390
391 puts "dictionary is now \"$myDict\""
392 # prints: dictionary is now "a {total 6} b {total 15}"
393
394 When dict with is used with a key that clashes with the name of the
395 dictionary variable:
396
397 set foo {foo {a b} bar 2 baz 3}
398 dict with foo {}
399 puts $foo
400 # prints: a b foo {a b} bar 2 baz 3
401
403 append(n), array(n), foreach(n), incr(n), list(n), lappend(n), lmap(n),
404 set(n)
405
407 dictionary, create, update, lookup, iterate, filter, map
408
409
410
411Tcl 8.5 dict(n)