For one reason or another I always need to uniquely
sort an array, by string value. Using lists is fine, but it gets messy, and doesn't really allow you to become very complex with the stored data.
I know tclx has keyed lists and that 8.4 has
improvements, but has anyone else ever figured out how
to pass an array to a function and return it sorted in
base tcl?
I came up with this, but I feel it is very flawed.
If anyone has a better idea, even with the value
passing from different stack levels or a way to rename
the global array in the calling scope to the original array name that would be great.
proc sort_array {arr {lvl "#0"}} {
global loc_arr
upvar $lvl $arr loc
set orig [subst -novariables $arr]
array set loc_arr {}
set x 0
foreach elem [array names loc] {
set loc_arr([incr x]) $loc($elem)
}
for {set i 1} {$i <= [array size loc_arr]} {incr i} {
for {set m 1} {$m <= [array size loc_arr]} {incr m} {
if {[string compare $loc_arr($i) $loc_arr($m)] == 0} {
set t $loc_arr($i)
set loc_arr($m) "" ; set loc_arr($i) ""
set loc_arr($i) $t
puts "Element $i val to $t."
}
}
}
foreach el [array names loc_arr] {
if {[string length $loc_arr($el)] < 1} {
unset loc_arr($el)
}
}
uplevel $lvl "array unset $orig"
return
}
HAVE A NICE WEEKEND.
sort an array, by string value. Using lists is fine, but it gets messy, and doesn't really allow you to become very complex with the stored data.
I know tclx has keyed lists and that 8.4 has
improvements, but has anyone else ever figured out how
to pass an array to a function and return it sorted in
base tcl?
I came up with this, but I feel it is very flawed.
If anyone has a better idea, even with the value
passing from different stack levels or a way to rename
the global array in the calling scope to the original array name that would be great.
proc sort_array {arr {lvl "#0"}} {
global loc_arr
upvar $lvl $arr loc
set orig [subst -novariables $arr]
array set loc_arr {}
set x 0
foreach elem [array names loc] {
set loc_arr([incr x]) $loc($elem)
}
for {set i 1} {$i <= [array size loc_arr]} {incr i} {
for {set m 1} {$m <= [array size loc_arr]} {incr m} {
if {[string compare $loc_arr($i) $loc_arr($m)] == 0} {
set t $loc_arr($i)
set loc_arr($m) "" ; set loc_arr($i) ""
set loc_arr($i) $t
puts "Element $i val to $t."
}
}
}
foreach el [array names loc_arr] {
if {[string length $loc_arr($el)] < 1} {
unset loc_arr($el)
}
}
uplevel $lvl "array unset $orig"
return
}
HAVE A NICE WEEKEND.