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