Purpose: Definition and discussion of set functionality, especially the function to compute intersection and both differences for two sets.
Back to the Chart of proposed set functionality.
Arguments:
Result:
This is a convenience function.
Implementation:
Several variants are possible:
The idea of using the local namespace as implicit array cannot be used here, sorry. But maybe variant B is boosted high enough to outoperform the other variants.
Shortcuts to use in the code:
Timing:
Summary:
Variant A.
proc ::setops::intersect3 {a b} { if {[llength $a] == 0} { return [list {} {} $b] } if {[llength $b] == 0} { return [list {} $a {}] } set res_is {} set res_ab {} set res_ba {} set a [lsort $a] set b [lsort $b] while {1} { # Store lindex/0,1 in var, access later faster ? set n [string compare [lindex $a 0] [lindex $b 0]] if {$n == 0} { # A = B => element in both, add to intersection. lappend res_is [lindex $a 0] set a [lrange $a 1 end] set b [lrange $b 1 end] } elseif {$n > 0} { # A > B, remove B, we are beyond the element. # This element in B is part of B-A. lappend res_ba [lindex $b 0] set b [lrange $b 1 end] } else { # A < B, remove A, we are beyond the element. # This element in A is part of A-B. lappend res_ab [lindex $a 0] set a [lrange $a 1 end] } if {[llength $a] == 0} { foreach e $b { lappend res_ba $e } return [list $res_is $res_ab $res_ba] } if {[llength $b] == 0} { foreach e $a { lappend res_ab $e } return [list $res_is $res_ab $res_ba] } } return [list $res_is $res_ab $res_ba] }
Variant B.
proc ::setops::intersect3 {a b} { list [Intersect2 $a $b] [diff $a $b] [diff $b $a] }
Variant C.
proc ::setops::intersect3 {a b} { if {[llength $a] == 0} { return [list {} {} $b] } if {[llength $b] == 0} { return [list {} $a {}] } set res_i {} set res_ab {} set res_ba {} foreach e $b { set ba($e) . } foreach e $a { set aa($e) . } foreach e $a { if {![info exists ba($e)]} { lappend res_ab $e } else { lappend res_i $e } } foreach e $b { if {![info exists aa($e)]} { lappend res_ba $e } else { lappend res_i $e } } list $res_i $res_ab $res_ba }
-- AK