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