Version 1 of dict for

Updated 2010-10-17 01:12:49 by AMG

dict for {keyVar valueVar} dictionaryValue body

This command takes three arguments, the first a two-element list of variable names (for the key and value respectively of each mapping in the dictionary), the second the dictionary value to iterate across, and the third a script to be evaluated for each mapping with the key and value variables set appropriately (in the manner of foreach.) The result of the command is an empty string. If any evaluation of the body generates a TCL_BREAK result, no further pairs from the dictionary will be iterated over and the dict for command will terminate successfully immediately. If any evaluation of the body generates a TCL_CONTINUE result, this shall be treated exactly like a normal TCL_OK result. The order of iteration is the order in which the keys were inserted into the dictionary.

# Data for one employee
dict set employeeInfo 12345-A forenames "Joe"
dict set employeeInfo 12345-A surname   "Schmoe"
dict set employeeInfo 12345-A street "147 Short Street"
dict set employeeInfo 12345-A city   "Springfield"
dict set employeeInfo 12345-A phone  "555-1234"
# Data for another employee
dict set employeeInfo 98372-J forenames "Anne"
dict set employeeInfo 98372-J surname   "Other"
dict set employeeInfo 98372-J street "32995 Oakdale Way"
dict set employeeInfo 98372-J city   "Springfield"
dict set employeeInfo 98372-J phone  "555-8765"
# The above data probably ought to come from a database...

# Print out some employee info
set i 0
puts "There are [dict size $employeeInfo] employees"
dict for {id info} $employeeInfo {
    puts "Employee #[incr i]: $id"
    dict with info {
        puts "   Name: $forenames $surname"
        puts "   Address: $street, $city"
        puts "   Telephone: $phone"
    }
}
# Another way to iterate and pick out names...
foreach id [dict keys $employeeInfo] {
    puts "Hello, [dict get $employeeInfo $id forenames]!"
}

AMG: [dict for] and [foreach] behave a little differently when applied to a key/value list with duplicate keys:

% set mydata {a 1 a 2 b 3 b 4}
a 1 a 2 b 3 b 4
% foreach {k v} $mydata {puts $k=$v}
a=1
a=2
b=3
b=4
% dict for {k v} $mydata {puts $k=$v}
a=2
b=4

[dict for] converts the list to a dict. In the process it discards all but the last instance of each key. By the way, this doesn't mean that data's is gone for good; it's still present in the string representation, so it'll reappear when the data is later used as a list or string.

[dict for] and [foreach] also disagree in their handling of odd-length lists. [dict for] will give the error "missing value to go with key", whereas [foreach] will behave as if the list had an empty string element appended to it.