Is there a simple way to count the number of matching elements in a list? The answer is "Yes. Several ways." ---- And just to keep things interesting, we can compare them in the context of a little test harness that times how quickly they run. There are many times when a Tcl programmer might want to compare a couple of different techniques to see which is fastest. The '''time''' command can often help. (See the [Tcl Performance] page for more information on speed improvements.) -- RWT #!/bin/sh # restart on the next line using tclsh \ exec tclsh "$0" "$@" #---------------------------------------- # Define procs to test each method for # counting identical list items. This # enables the byte-code compiler to # optimize the code. #---------------------------------------- proc count_members1 list { foreach member $list { if {[info exists count($member)]} { incr count($member) } else { set count($member) 1 } } } proc count_members2 list { foreach x $list { if {[catch {incr count($x)}]} {set count($x) 1} } } proc count_members3 list { foreach x $list { expr {[catch {incr count($x)}] && [set count($x) 1]} } } proc count_members4 list { foreach x $list { lappend ulist($x) {} } foreach name [array names ulist] { set count($name) [llength $ulist($name)] } } proc count_members5 list { foreach x $list { append ulist($x) . } foreach name [array names ulist] { set count($name) [string length $ulist($name)] } } #---------------------------------------- # Create some test data. In this case, # build a list of 10,000 items #---------------------------------------- set items [list john paul jones mary] for {set i 0} {$i<10000} {incr i} { lappend data [lindex $items [expr {int(rand()*[llength $items])}]] } #---------------------------------------- # Print some information about our # environment. This is very useful # when consulting comp.lang.tcl. #---------------------------------------- puts "[info patchlevel] over $tcl_platform(os) $tcl_platform(osVersion)." #---------------------------------------- # Run the tests. # Note that we have cleverly named # the test procs so that [info] can # easily find and execute them. #---------------------------------------- foreach proc [info proc count_members*] { puts "" puts "$proc" puts [time {$proc $data} 10] } ---- See [Chart of proposed list functionality] too. ---- [Category Command]