| [25] | 1 | '\" |
|---|
| 2 | '\" Copyright (c) 2003 Donal K. Fellows |
|---|
| 3 | '\" |
|---|
| 4 | '\" See the file "license.terms" for information on usage and redistribution |
|---|
| 5 | '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. |
|---|
| 6 | '\" |
|---|
| 7 | '\" RCS: @(#) $Id: dict.n,v 1.18 2007/12/31 00:17:44 dkf Exp $ |
|---|
| 8 | '\" |
|---|
| 9 | .so man.macros |
|---|
| 10 | .TH dict n 8.5 Tcl "Tcl Built-In Commands" |
|---|
| 11 | .BS |
|---|
| 12 | '\" Note: do not modify the .SH NAME line immediately below! |
|---|
| 13 | .SH NAME |
|---|
| 14 | dict \- Manipulate dictionaries |
|---|
| 15 | .SH SYNOPSIS |
|---|
| 16 | \fBdict \fIoption arg \fR?\fIarg ...\fR? |
|---|
| 17 | .BE |
|---|
| 18 | .SH DESCRIPTION |
|---|
| 19 | .PP |
|---|
| 20 | Performs one of several operations on dictionary values or variables |
|---|
| 21 | containing dictionary values (see the \fBDICTIONARY VALUES\fR section |
|---|
| 22 | below for a description), depending on \fIoption\fR. The legal |
|---|
| 23 | \fIoption\fRs (which may be abbreviated) are: |
|---|
| 24 | .TP |
|---|
| 25 | \fBdict append \fIdictionaryVariable key \fR?\fIstring ...\fR? |
|---|
| 26 | This appends the given string (or strings) to the value that the given |
|---|
| 27 | key maps to in the dictionary value contained in the given variable, |
|---|
| 28 | writing the resulting dictionary value back to that variable. |
|---|
| 29 | Non-existent keys are treated as if they map to an empty string. |
|---|
| 30 | .TP |
|---|
| 31 | \fBdict create \fR?\fIkey value ...\fR? |
|---|
| 32 | Create a new dictionary that contains each of the key/value mappings |
|---|
| 33 | listed as arguments (keys and values alternating, with each key being |
|---|
| 34 | followed by its associated value.) |
|---|
| 35 | .TP |
|---|
| 36 | \fBdict exists \fIdictionaryValue key \fR?\fIkey ...\fR? |
|---|
| 37 | This returns a boolean value indicating whether the given key (or path |
|---|
| 38 | of keys through a set of nested dictionaries) exists in the given |
|---|
| 39 | dictionary value. This returns a true value exactly when \fBdict |
|---|
| 40 | get\fR on that path will succeed. |
|---|
| 41 | .TP |
|---|
| 42 | \fBdict filter \fIdictionaryValue filterType arg \fR?\fIarg ...\fR? |
|---|
| 43 | This takes a dictionary value and returns a new dictionary that |
|---|
| 44 | contains just those key/value pairs that match the specified filter |
|---|
| 45 | type (which may be abbreviated.) Supported filter types are: |
|---|
| 46 | .RS |
|---|
| 47 | .TP |
|---|
| 48 | \fBdict filter \fIdictionaryValue \fBkey \fIglobPattern\fR |
|---|
| 49 | The key rule only matches those key/value pairs whose keys match the |
|---|
| 50 | given pattern (in the style of \fBstring match\fR.) |
|---|
| 51 | .TP |
|---|
| 52 | \fBdict filter \fIdictionaryValue \fBscript {\fIkeyVar valueVar\fB} \fIscript\fR |
|---|
| 53 | The script rule tests for matching by assigning the key to the |
|---|
| 54 | \fIkeyVar\fR and the value to the \fIvalueVar\fR, and then evaluating |
|---|
| 55 | the given script which should return a boolean value (with the |
|---|
| 56 | key/value pair only being included in the result of the \fBdict |
|---|
| 57 | filter\fR when a true value is returned.) Note that the first |
|---|
| 58 | argument after the rule selection word is a two-element list. If the |
|---|
| 59 | \fIscript\fR returns with a condition of \fBTCL_BREAK\fR, no further |
|---|
| 60 | key/value pairs are considered for inclusion in the resulting |
|---|
| 61 | dictionary, and a condition of \fBTCL_CONTINUE\fR is equivalent to a false |
|---|
| 62 | result. The key/value pairs are tested in the order in which the keys |
|---|
| 63 | were inserted into the dictionary. |
|---|
| 64 | .TP |
|---|
| 65 | \fBdict filter \fIdictionaryValue \fBvalue \fIglobPattern\fR |
|---|
| 66 | The value rule only matches those key/value pairs whose values match |
|---|
| 67 | the given pattern (in the style of \fBstring match\fR.) |
|---|
| 68 | .RE |
|---|
| 69 | .TP |
|---|
| 70 | \fBdict for {\fIkeyVar valueVar\fB} \fIdictionaryValue body\fR |
|---|
| 71 | This command takes three arguments, the first a two-element list of |
|---|
| 72 | variable names (for the key and value respectively of each mapping in |
|---|
| 73 | the dictionary), the second the dictionary value to iterate across, |
|---|
| 74 | and the third a script to be evaluated for each mapping with the key |
|---|
| 75 | and value variables set appropriately (in the manner of \fBforeach\fR.) |
|---|
| 76 | The result of the command is an empty string. If any evaluation of the |
|---|
| 77 | body generates a \fBTCL_BREAK\fR result, no further pairs from the |
|---|
| 78 | dictionary will be iterated over and the \fBdict for\fR command will |
|---|
| 79 | terminate successfully immediately. If any evaluation of the body |
|---|
| 80 | generates a \fBTCL_CONTINUE\fR result, this shall be treated exactly like a |
|---|
| 81 | normal \fBTCL_OK\fR result. The order of iteration is the order in |
|---|
| 82 | which the keys were inserted into the dictionary. |
|---|
| 83 | .TP |
|---|
| 84 | \fBdict get \fIdictionaryValue \fR?\fIkey ...\fR? |
|---|
| 85 | Given a dictionary value (first argument) and a key (second argument), |
|---|
| 86 | this will retrieve the value for that key. Where several keys are |
|---|
| 87 | supplied, the behaviour of the command shall be as if the result of |
|---|
| 88 | \fBdict get $dictVal $key\fR was passed as the first argument to |
|---|
| 89 | \fBdict get\fR with the remaining arguments as second (and possibly |
|---|
| 90 | subsequent) arguments. This facilitates lookups in nested |
|---|
| 91 | dictionaries. For example, the following two commands are equivalent: |
|---|
| 92 | .RS |
|---|
| 93 | .CS |
|---|
| 94 | dict get $dict foo bar spong |
|---|
| 95 | dict get [dict get [dict get $dict foo] bar] spong |
|---|
| 96 | .CE |
|---|
| 97 | If no keys are provided, dict would return a list containing pairs of |
|---|
| 98 | elements in a manner similar to \fBarray get\fR. That is, the first |
|---|
| 99 | element of each pair would be the key and the second element would be |
|---|
| 100 | the value for that key. |
|---|
| 101 | |
|---|
| 102 | It is an error to attempt to retrieve a value for a key that is not |
|---|
| 103 | present in the dictionary. |
|---|
| 104 | .RE |
|---|
| 105 | .TP |
|---|
| 106 | \fBdict incr \fIdictionaryVariable key \fR?\fIincrement\fR? |
|---|
| 107 | This adds the given increment value (an integer that defaults to 1 if |
|---|
| 108 | not specified) to the value that the given key maps to in the |
|---|
| 109 | dictionary value contained in the given variable, writing the |
|---|
| 110 | resulting dictionary value back to that variable. Non-existent keys |
|---|
| 111 | are treated as if they map to 0. It is an error to increment a value |
|---|
| 112 | for an existing key if that value is not an integer. |
|---|
| 113 | .TP |
|---|
| 114 | \fBdict info \fIdictionaryValue\fR |
|---|
| 115 | This returns information (intended for display to people) about the |
|---|
| 116 | given dictionary though the format of this data is dependent on the |
|---|
| 117 | implementation of the dictionary. For dictionaries that are |
|---|
| 118 | implemented by hash tables, it is expected that this will return the |
|---|
| 119 | string produced by \fBTcl_HashStats\fR, similar to \fBarray info\fR. |
|---|
| 120 | .TP |
|---|
| 121 | \fBdict keys \fIdictionaryValue \fR?\fIglobPattern\fR? |
|---|
| 122 | Return a list of all keys in the given dictionary value. If a pattern |
|---|
| 123 | is supplied, only those keys that match it (according to the rules of |
|---|
| 124 | \fBstring match\fR) will be returned. The returned keys will be in the |
|---|
| 125 | order that they were inserted into the dictionary. |
|---|
| 126 | .TP |
|---|
| 127 | \fBdict lappend \fIdictionaryVariable key \fR?\fIvalue ...\fR? |
|---|
| 128 | This appends the given items to the list value that the given key maps |
|---|
| 129 | to in the dictionary value contained in the given variable, writing |
|---|
| 130 | the resulting dictionary value back to that variable. Non-existent |
|---|
| 131 | keys are treated as if they map to an empty list, and it is legal for |
|---|
| 132 | there to be no items to append to the list. It is an error for the |
|---|
| 133 | value that the key maps to to not be representable as a list. |
|---|
| 134 | .TP |
|---|
| 135 | \fBdict merge \fR?\fIdictionaryValue ...\fR? |
|---|
| 136 | Return a dictionary that contains the contents of each of the |
|---|
| 137 | \fIdictionaryValue\fR arguments. Where two (or more) dictionaries |
|---|
| 138 | contain a mapping for the same key, the resulting dictionary maps that |
|---|
| 139 | key to the value according to the last dictionary on the command line |
|---|
| 140 | containing a mapping for that key. |
|---|
| 141 | .TP |
|---|
| 142 | \fBdict remove \fIdictionaryValue \fR?\fIkey ...\fR? |
|---|
| 143 | Return a new dictionary that is a copy of an old one passed in as |
|---|
| 144 | first argument except without mappings for each of the keys listed. |
|---|
| 145 | It is legal for there to be no keys to remove, and it also legal for |
|---|
| 146 | any of the keys to be removed to not be present in the input |
|---|
| 147 | dictionary in the first place. |
|---|
| 148 | .TP |
|---|
| 149 | \fBdict replace \fIdictionaryValue \fR?\fIkey value ...\fR? |
|---|
| 150 | Return a new dictionary that is a copy of an old one passed in as |
|---|
| 151 | first argument except with some values different or some extra |
|---|
| 152 | key/value pairs added. It is legal for this command to be called with |
|---|
| 153 | no key/value pairs, but illegal for this command to be called with a |
|---|
| 154 | key but no value. |
|---|
| 155 | .TP |
|---|
| 156 | \fBdict set \fIdictionaryVariable key \fR?\fIkey ...\fR? \fIvalue\fR |
|---|
| 157 | This operation takes the name of a variable containing a dictionary |
|---|
| 158 | value and places an updated dictionary value in that variable |
|---|
| 159 | containing a mapping from the given key to the given value. When |
|---|
| 160 | multiple keys are present, this operation creates or updates a chain |
|---|
| 161 | of nested dictionaries. |
|---|
| 162 | .TP |
|---|
| 163 | \fBdict size \fIdictionaryValue\fR |
|---|
| 164 | Return the number of key/value mappings in the given dictionary value. |
|---|
| 165 | .TP |
|---|
| 166 | \fBdict unset \fIdictionaryVariable key \fR?\fIkey ...\fR? |
|---|
| 167 | This operation (the companion to \fBdict set\fR) takes the name of a |
|---|
| 168 | variable containing a dictionary value and places an updated |
|---|
| 169 | dictionary value in that variable that does not contain a mapping for |
|---|
| 170 | the given key. Where multiple keys are present, this describes a path |
|---|
| 171 | through nested dictionaries to the mapping to remove. At least one key |
|---|
| 172 | must be specified, but the last key on the key-path need not exist. |
|---|
| 173 | All other components on the path must exist. |
|---|
| 174 | .TP |
|---|
| 175 | \fBdict update \fIdictionaryVariable key varName \fR?\fIkey varName ...\fR? \fIbody\fR |
|---|
| 176 | Execute the Tcl script in \fIbody\fR with the value for each \fIkey\fR |
|---|
| 177 | (as found by reading the dictionary value in \fIdictionaryVariable\fR) |
|---|
| 178 | mapped to the variable \fIvarName\fR. There may be multiple |
|---|
| 179 | \fIkey\fR/\fIvarName\fR pairs. If a \fIkey\fR does not have a mapping, |
|---|
| 180 | that corresponds to an unset \fIvarName\fR. When \fIbody\fR |
|---|
| 181 | terminates, any changes made to the \fIvarName\fRs is reflected back |
|---|
| 182 | to the dictionary within \fIdictionaryVariable\fR (unless |
|---|
| 183 | \fIdictionaryVariable\fR itself becomes unreadable, when all updates |
|---|
| 184 | are silently discarded), even if the result of \fIbody\fR is an error |
|---|
| 185 | or some other kind of exceptional exit. The result of \fBdict |
|---|
| 186 | update\fR is (unless some kind of error occurs) the result of the |
|---|
| 187 | evaluation of \fIbody\fR. Note that the mapping of values to variables |
|---|
| 188 | does not use traces; changes to the \fIdictionaryVariable\fR's |
|---|
| 189 | contents only happen when \fIbody\fR terminates. |
|---|
| 190 | .TP |
|---|
| 191 | \fBdict values \fIdictionaryValue \fR?\fIglobPattern\fR? |
|---|
| 192 | Return a list of all values in the given dictionary value. If a |
|---|
| 193 | pattern is supplied, only those values that match it (according to the |
|---|
| 194 | rules of \fBstring match\fR) will be returned. The returned values |
|---|
| 195 | will be in the order of that the keys associated with those values |
|---|
| 196 | were inserted into the dictionary. |
|---|
| 197 | .TP |
|---|
| 198 | \fBdict with \fIdictionaryVariable \fR?\fIkey ...\fR? \fIbody\fR |
|---|
| 199 | Execute the Tcl script in \fIbody\fR with the value for each key in |
|---|
| 200 | \fIdictionaryVariable\fR mapped (in a manner similarly to \fBdict |
|---|
| 201 | update\fR) to a variable with the same name. Where one or more |
|---|
| 202 | \fIkey\fRs are available, these indicate a chain of nested |
|---|
| 203 | dictionaries, with the innermost dictionary being the one opened out |
|---|
| 204 | for the execution of \fIbody\fR. As with \fBdict update\fR, making |
|---|
| 205 | \fIdictionaryVariable\fR unreadable will make the updates to the |
|---|
| 206 | dictionary be discarded, and this also happens if the contents of |
|---|
| 207 | \fIdictionaryVariable\fR are adjusted so that the chain of |
|---|
| 208 | dictionaries no longer exists. The result of \fBdict with\fR is |
|---|
| 209 | (unless some kind of error occurs) the result of the evaluation of |
|---|
| 210 | \fIbody\fR. Note that the mapping of values to variables does not use |
|---|
| 211 | traces; changes to the \fIdictionaryVariable\fR's contents only happen |
|---|
| 212 | when \fIbody\fR terminates. |
|---|
| 213 | .SH "DICTIONARY VALUES" |
|---|
| 214 | Dictionaries are values that contain an efficient, order-preserving |
|---|
| 215 | mapping from arbitrary keys to arbitrary values. |
|---|
| 216 | Each key in the dictionary maps to a single value. |
|---|
| 217 | They have a textual format that is exactly that of any list with an |
|---|
| 218 | even number of elements, with each mapping in the dictionary being |
|---|
| 219 | represented as two items in the list. When a command takes a |
|---|
| 220 | dictionary and produces a new dictionary based on it (either returning |
|---|
| 221 | it or writing it back into the variable that the starting dictionary |
|---|
| 222 | was read from) the new dictionary will have the same order of keys, |
|---|
| 223 | modulo any deleted keys and with new keys added on to the end. |
|---|
| 224 | When a string is interpreted as a dictionary and it would otherwise |
|---|
| 225 | have duplicate keys, only the last value for a particular key is used; |
|---|
| 226 | the others are ignored, meaning that, |
|---|
| 227 | .QW "apple banana" |
|---|
| 228 | and |
|---|
| 229 | .QW "apple carrot apple banana" |
|---|
| 230 | are equivalent dictionaries (with different string representations). |
|---|
| 231 | .SH EXAMPLES |
|---|
| 232 | Constructing and using nested dictionaries: |
|---|
| 233 | .CS |
|---|
| 234 | # Data for one employee |
|---|
| 235 | \fBdict set\fR employeeInfo 12345-A forenames "Joe" |
|---|
| 236 | \fBdict set\fR employeeInfo 12345-A surname "Schmoe" |
|---|
| 237 | \fBdict set\fR employeeInfo 12345-A street "147 Short Street" |
|---|
| 238 | \fBdict set\fR employeeInfo 12345-A city "Springfield" |
|---|
| 239 | \fBdict set\fR employeeInfo 12345-A phone "555-1234" |
|---|
| 240 | # Data for another employee |
|---|
| 241 | \fBdict set\fR employeeInfo 98372-J forenames "Anne" |
|---|
| 242 | \fBdict set\fR employeeInfo 98372-J surname "Other" |
|---|
| 243 | \fBdict set\fR employeeInfo 98372-J street "32995 Oakdale Way" |
|---|
| 244 | \fBdict set\fR employeeInfo 98372-J city "Springfield" |
|---|
| 245 | \fBdict set\fR employeeInfo 98372-J phone "555-8765" |
|---|
| 246 | # The above data probably ought to come from a database... |
|---|
| 247 | |
|---|
| 248 | # Print out some employee info |
|---|
| 249 | set i 0 |
|---|
| 250 | puts "There are [\fBdict size\fR $employeeInfo] employees" |
|---|
| 251 | \fBdict for\fR {id info} $employeeInfo { |
|---|
| 252 | puts "Employee #[incr i]: $id" |
|---|
| 253 | \fBdict with\fR info { |
|---|
| 254 | puts " Name: $forenames $surname" |
|---|
| 255 | puts " Address: $street, $city" |
|---|
| 256 | puts " Telephone: $phone" |
|---|
| 257 | } |
|---|
| 258 | } |
|---|
| 259 | # Another way to iterate and pick out names... |
|---|
| 260 | foreach id [\fBdict keys\fR $employeeInfo] { |
|---|
| 261 | puts "Hello, [\fBdict get\fR $employeeInfo $id forenames]!" |
|---|
| 262 | } |
|---|
| 263 | .CE |
|---|
| 264 | .PP |
|---|
| 265 | A localizable version of \fBstring toupper\fR: |
|---|
| 266 | .CS |
|---|
| 267 | # Set up the basic C locale |
|---|
| 268 | set capital [\fBdict create\fR C [\fBdict create\fR]] |
|---|
| 269 | foreach c [split {abcdefghijklmnopqrstuvwxyz} ""] { |
|---|
| 270 | \fBdict set\fR capital C $c [string toupper $c] |
|---|
| 271 | } |
|---|
| 272 | |
|---|
| 273 | # English locales can luckily share the "C" locale |
|---|
| 274 | \fBdict set\fR capital en [\fBdict get\fR $capital C] |
|---|
| 275 | \fBdict set\fR capital en_US [\fBdict get\fR $capital C] |
|---|
| 276 | \fBdict set\fR capital en_GB [\fBdict get\fR $capital C] |
|---|
| 277 | |
|---|
| 278 | # ... and so on for other supported languages ... |
|---|
| 279 | |
|---|
| 280 | # Now get the mapping for the current locale and use it. |
|---|
| 281 | set upperCaseMap [\fBdict get\fR $capital $env(LANG)] |
|---|
| 282 | set upperCase [string map $upperCaseMap $string] |
|---|
| 283 | .CE |
|---|
| 284 | .SH "SEE ALSO" |
|---|
| 285 | append(n), array(n), foreach(n), incr(n), list(n), lappend(n), set(n) |
|---|
| 286 | .SH KEYWORDS |
|---|
| 287 | dictionary, create, update, lookup, iterate, filter |
|---|