set tbl {{firstname lastname phone}}Note the double bracing, which makes sure tbl is a 1-element list. Adding "records" to the table is as easy as lappend tbl {John Smith (123)456-7890}Make sure the fields (cells) match those in the header. Here single bracing is correct. If a field content contains spaces, it must be quoted or braced too: lappend tbl {{George W} Bush 234-5678}Sorting a table can be done with lsort -index, taking care that the header line stays on top: proc tsort args {
set table [lindex $args end]
set header [lindex $table 0]
set res [eval lsort [lrange $args 0 end-1] [list [lrange $table 1 end]]]
linsert $res 0 $header
}Removing a row (or contiguous sequence of rows) by numeric index is a job for lreplace:set tbl [lreplace $tbl $from $to]Simple printing of such a table, a row per line, is easy with
puts [join $tbl \n]Accessing fields in a table is more fun with the field names than the numeric indexes, which is made easy by the fact that the field names are in the first row:
proc t@ {tbl field} {lsearch [lindex $tbl 0] $field}
% t@ $tbl phone
2You can then access cells:puts [lindex $tbl $rownumber [t@ $tbl lastname]]and replace cell contents like this:
lset tbl $rownumber [t@ $tbl phone] (222)333-4567Here is how to filter a table by giving pairs of field name and glob-style expression - in addition to the header line, all rows that satisfy at least one of those come through (you can force AND behavior by just nesting such calls):
proc trows {tbl args} {
set conditions {}
foreach {field condition} $args {
lappend conditions [t@ $tbl $field] $condition
}
set res [list [lindex $tbl 0]]
foreach row [lrange $tbl 1 end] {
foreach {index condition} $conditions {
if [string match $condition [lindex $row $index]] {
lappend res $row
break; # one hit is sufficient
}
}
}
set res
}
% trows $tbl lastname Sm*
{firstname lastname} phone {John Smith (123)456-7890}This filters (and, if wanted, rearranges) columns, sort of what is called a "view": proc tcols {tbl args} {
set indices {}
foreach field $args {lappend indices [t@ $tbl $field]}
set res {}
foreach row $tbl {
set newrow {}
foreach index $indices {lappend newrow [lindex $row $index]}
lappend res $newrow
}
set res
}See also matrix, Tkcon, "Displaying Tables", TkTable, ... See also starbase
Category Concept | Arts and crafts of Tcl-Tk programming

