From: iand on 17 May 2010 04:24 Is there any command which helps remove the elements of a list with specified indices? lrem $list -indices {$indexlist} or lrem $list -indices {0 3 5 8} which reconstructs the list removing the elements at indices mentioned. lreplace, lindex works with the ranges but not helpful with discrete indices. Please help. Cheers, iand
From: jr4412 on 17 May 2010 07:19 hi iand, On May 17, 9:24 am, iand <ianda...(a)gmail.com> wrote: > Is there any command which helps remove the elements of a list with > specified indices? > lrem $list -indices {$indexlist} > or > lrem $list -indices {0 3 5 8} which reconstructs the list removing the > elements at indices mentioned. > lreplace, lindex works with the ranges but not helpful with discrete > indices. > > Please help. > > Cheers, > iand yes, there will be a 'lrem' command as soon as you write the procedure which wraps the required lreplace etc command(s) -- that's what extensibility is all about ;)
From: Larry W. Virden on 17 May 2010 07:38 On May 17, 4:24 am, iand <ianda...(a)gmail.com> wrote: > Is there any command which helps remove the elements of a list with > specified indices? The idea you are asking about is the ability to say "delete members 1 3 5 and 7 of list xyz"? I don't know of a specific variety of lreplace to do that. However, it seems to me that something like this pseudo code would be possible proc lrem { inList args } { if { ! [string equal [lindex $args 0] "-indices"]} { puts stderr "USAGE: $::argv0 list -indices {indexlist}" return {} } set indices [lrange $args 1 end] puts "indices = $indices" set sortedindices [ lsort -integer -decreasing {*}$indices] puts "sortedindices = $sortedindices" foreach i $sortedindices { puts "i = $i" set inList [lreplace $inList $i $i] puts "inList = $inList" } puts "returning inList = $inList" return $inList } set l [list 1 a 2 b 3 c 4 d] set rc [lrem $l -indices [list 2 4 6]] puts "rc = $rc"
From: Qatanah on 17 May 2010 09:30 On May 17, 4:24 pm, iand <ianda...(a)gmail.com> wrote: > Is there any command which helps remove the elements of a list with > specified indices? > lrem $list -indices {$indexlist} > or > lrem $list -indices {0 3 5 8} which reconstructs the list removing the > elements at indices mentioned. > lreplace, lindex works with the ranges but not helpful with discrete > indices. > > Please help. > > Cheers, > iand I think there was a wrapper proc introduce in a book. The proc name was 'ldelete'..
From: tom.rmadilo on 17 May 2010 14:12 On May 17, 1:24 am, iand <ianda...(a)gmail.com> wrote: > Is there any command which helps remove the elements of a list with > specified indices? > lrem $list -indices {$indexlist} > or > lrem $list -indices {0 3 5 8} which reconstructs the list removing the > elements at indices mentioned. > lreplace, lindex works with the ranges but not helpful with discrete > indices. Here is a version which takes care of a number of potential problems: # Note: lranges returns potentially overlapping ranges proc ::lranges { listVar {lRanges {{0 end}}} } { upvar $listVar inList set outList [list] foreach range $lRanges { lappend outList {*}[lrange $inList {*}$range] } return $outList } # lremove removes ranges from list by # first inverting the list, then using lranges. # Ugly, but seems to work: proc ::lremove { listVar {lRanges {{0 end}}} } { upvar $listVar inList set endIndex [expr {[llength $inList] - 1}] set rBegin 0 set rEnd $endIndex set outRanges [list] puts "lRanges = $lRanges" foreach range [lsort -integer -index 0\ [lsort -integer -index 1 -decreasing\ [string map [list end $endIndex] $lRanges]]] { set rangeBegin [expr [lindex $range 0]] set rangeEnd [expr [lindex $range 1]] puts "range = '$range', rBegin = $rBegin, rEnd = $rEnd, rangeBegin = $rangeBegin rangeEnd = $rangeEnd" if {$rangeBegin == $rBegin} { set rBegin [expr $rangeEnd+1] lappend begin $rBegin lappend end $rEnd continue } if {$rangeEnd == $rEnd} { set rEnd [expr $rangeBegin-1] lappend begin $rBegin lappend end $rEnd continue } lappend begin $rBegin lappend end [expr $rangeBegin -1] lappend begin [expr $rangeEnd+1] lappend end $rEnd } set begin [lsort -integer -unique $begin] set end [lsort -integer -unique $end] puts "begin = $begin, end = $end" puts "rBegin = $rBegin, rEnd = $rEnd" set i 0 foreach beg $begin { if {$beg < $rBegin} { set beg $rBegin } set en [lindex $end $i] if {$en eq ""} { break } elseif {$en > $rEnd} { set en $rEnd } lappend outRanges [list $beg $en] incr i } puts "outRanges = [lsort -unique $outRanges]" #return [lsort -unique $outRanges] return [lranges inList [lsort -unique $outRanges]] } # Example: set list [list a b c d e f g h i j] lremove list [list {0 5}] lremove list [list {0 2}] lremove list [list {0 2} {3 5}] puts "[lremove list {{3 5} {0 2} {8 9}}]" # should return "g h" as a two element list. Note that [lremove] works with "end", but not with "end-1", etc.
|
Next
|
Last
Pages: 1 2 3 Prev: Text entry dialog widget pre-made? Next: Problem with Thread package on Aqua |