Back to the Chart of proposed set functionality. See also SetOps.
# --------------------------------------------- # SetOps -- Set operations for Tcl # # (C) c.l.t. community, 1999 # # $Id: 358,v 1.3 2003-03-21 09:00:45 jcw Exp $ # --------------------------------------------- # Implementation variant for tcl 7.6 and below. # It looks as if the procedures would use namespaces, # but they don't. For 7.6 the '::'s are just part of # the procedure name. It is especially not possible # to use the internal procedures in a shortcut manner # (without preceding ::setops::). # --------------------------------------------- proc ::setops::create {args} { if {[llength $args] == 0} { return {} } foreach $args {.} {break} unset args info locals } proc ::setops::contains {set element} { expr {[lsearch -exact $set $element] < 0 ? 0 : 1} } proc ::setops::union {args} { switch [llength $args] { 0 { return {} } 1 { return [lindex $args 0] } default { foreach __SETA__ $args { if {[llength $__SETA__] > 0} { foreach $__SETA__ {.} {break} } } unset args __SETA__ info locals } } } proc ::setops::Intersect2 {__SETA__ __SETB__} { if {[llength $__SETA__] == 0} { return {} } if {[llength $__SETB__] == 0} { return {} } set __RESULT__ {} if {[llength $__SETA__] < [llength $__SETB__]} { foreach $__SETB__ {.} {break} foreach __ITEM__ $__SETA__ { if {[info exists $__ITEM__]} { lappend __RESULT__ $__ITEM__ } } } else { foreach $__SETA__ {.} {break} foreach __ITEM__ $__SETB__ { if {[info exists $__ITEM__]} { lappend __RESULT__ $__ITEM__ } } } return $__RESULT__ } proc ::setops::intersect {args} { switch [llength $args] { 0 { # Intersection of nothing is nothing return {} } 1 { return [lindex $args 0] } default { set res [lindex $args 0] set args [lrange $args 1 end] while {($res != {}) && ([llength $args] > 0)} { set res [::setops::Intersect2 $res [lindex $args 0]] set args [lrange $args 1 end] } return $res } } } proc ::setops::diff {__SETA__ __SETB__} { if {[llength $__SETA__] == 0} { return {} } if {[llength $__SETB__] == 0} { return $__SETA__ } set __RESULT__ {} foreach $__SETB__ {.} {break} foreach __ITEM__ $__SETA__ { if {![info exists $__ITEM__]} { lappend __RESULT__ $__ITEM__ } } return $__RESULT__ } proc ::setops::symdiff {a b} { ::setops::diff [::setops::union $a $b] [::setops::Intersect2 $a $b] } proc ::setops::empty {set} { expr {[llength $set] == 0} }