Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | list new routines list complement subset |
|---|---|
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA1: |
0b8c3fdd986366b8b2189468e425ed95 |
| User & Date: | pooryorick 2019-09-22 21:36:23.280 |
Context
|
2019-09-22
| ||
| 21:38 | tcl merged [armour] into [string printable] check-in: fd979799af user: pooryorick tags: trunk | |
| 21:36 | list new routines list complement subset check-in: 0b8c3fdd98 user: pooryorick tags: trunk | |
| 21:34 | ns fix bug in dupcmds check-in: a898b66be5 user: pooryorick tags: trunk | |
Changes
Changes to packages/list/lib/list.tcl.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
#! /bin/env tclsh
namespace import ::tcl::mathop::!
namespace import ::tcl::mathop::-
namespace import ::tcl::mathfunc::abs
namespace import ::tcl::mathfunc::max
package require {ycl proc}
[yclprefix]::proc alias [yclprefix]::proc::alias
alias [yclprefix]::proc::argsswitch
alias [yclprefix]::proc::checkargs
alias [yclprefix]::proc::optswitch
package require {ycl parse tcl commands}
alias [yclprefix]::parse::tcl::commands::commands
#package require struct::list
#namespace import ::struct::list::list
package require {ycl sugar}
alias [yclprefix]::sugar::block
| > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
#! /bin/env tclsh
namespace import ::tcl::mathop::!
namespace import ::tcl::mathop::-
namespace import ::tcl::mathfunc::abs
namespace import ::tcl::mathfunc::max
package require {ycl proc}
[yclprefix]::proc alias [yclprefix]::proc::alias
alias [yclprefix]::proc::argsswitch
alias [yclprefix]::proc::block
alias [yclprefix]::proc::checkargs
alias [yclprefix]::proc::optswitch
alias [yclprefix]::proc::stub
package require {ycl parse tcl commands}
alias [yclprefix]::parse::tcl::commands::commands
#package require struct::list
#namespace import ::struct::list::list
package require {ycl sugar}
alias [yclprefix]::sugar::block
|
| ︙ | ︙ | |||
161 162 163 164 165 166 167 168 169 170 171 172 173 174 |
break
}
incr i
}
return $res
}
proc cut {listname args} {
upvar $listname list
::foreach arg $args[set args 0] {
lassign $args first last
if {$last eq {}} {
set last $first
| > > > > > > > > > > > > > > > > > > > | 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 |
break
}
incr i
}
return $res
}
block {
foreach op {complement subset} {
try [string map [list @op@ $op] {
stub @op@ {list1name list2name} {
package require {ycl list list}
package require {ycl set}
alias yset [yclprefix]::set
} {
upvar $list1name list1 $list2name list2
set cmd1 [[list .spawn [info cmdcount]_list] .init list $list1]
set cmd2 [[list .spawn [info cmdcount]_list] .init list $list2]
set res [yset @op@ $cmd1 $cmd2]
rename $cmd1 {}
rename $cmd2 {}
return $res
}
}]
}
}
proc cut {listname args} {
upvar $listname list
::foreach arg $args[set args 0] {
lassign $args first last
if {$last eq {}} {
set last $first
|
| ︙ | ︙ | |||
309 310 311 312 313 314 315 |
variable doc::filter {
description {
Filters items out of a list using another list as a mask.
}
}
| | > > | | 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 |
variable doc::filter {
description {
Filters items out of a list using another list as a mask.
}
}
proc filter {listname mask} {
upvar $listname list
set res {}
::foreach item $list i $mask {
if {$i} {
::lappend res $item
}
}
set list $res[set res {}]
return
}
variable doc::consume {
description
like [foreach]
but accepts the names of lists
|
| ︙ | ︙ | |||
739 740 741 742 743 744 745 746 747 748 749 750 751 752 |
lindex item end
set res $item
lreplace list end end
return $res
}
}
proc prepend {varname args} {
upvar $varname var
# create the variable if it doesn't exist
lappend var
linsert var 0 {*}$args
return $var
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 |
lindex item end
set res $item
lreplace list end end
return $res
}
}
variable doc::prefix {
description
determine whether the value in $list1var is a prefix of the value in
$list2var
if $list1var is omitted
the name "prefix" is used
}
proc prefix {list1var args} {
llength args
if {$len} {
set list2var $args[set args {}]
lindex list2var 0
} else {
set list2var $list1var
set list1var prefix
}
upvar $list1var list1 $list2var list2
llength list1
::foreach item1 $list1 item2 $list2 {
if {$item1 ne $item2} {
set list1 0
return
}
if {[incr len -1] == 0} break
}
set list1 1
return
}
proc prepend {varname args} {
upvar $varname var
# create the variable if it doesn't exist
lappend var
linsert var 0 {*}$args
return $var
|
| ︙ | ︙ | |||
898 899 900 901 902 903 904 | description set the variable named $listname to the remaining items in a list after the items in $prefix if $listname is omitted the name "tail" is used } | < < | 954 955 956 957 958 959 960 961 962 963 964 965 966 967 |
description
set the variable named $listname to the remaining items in a list after
the items in $prefix
if $listname is omitted
the name "tail" is used
}
block {
set body {
llength args
@argswitch@
upvar $listname list
llength prefix
::foreach item1 $list item2 $prefix {
|
| ︙ | ︙ |
Changes to packages/list/lib/list.test.tcl.
| ︙ | ︙ | |||
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
interp alias {} [namespace current]::any {} [yclprefix] list any
interp alias {} [namespace current]::all {} [yclprefix] list all
interp alias {} [namespace current]::are {} [yclprefix] list are
interp alias {} [namespace current]::which {} [yclprefix] list which
namespace import [yclprefix]::list::add
namespace import [yclprefix]::list::addp
namespace import [yclprefix]::list::compare
namespace import [yclprefix]::list::consume
namespace import [yclprefix]::list::dedent
namespace import [yclprefix]::list::dedent_exact
namespace import [yclprefix]::list::filter
namespace import [yclprefix]::list::head
namespace import [yclprefix]::list::join
namespace import [yclprefix]::list::lappend
namespace import [yclprefix]::list::lappend*
namespace import [yclprefix]::list::lindex
namespace import [yclprefix]::list::linsert
namespace import [yclprefix]::list::llength
namespace import [yclprefix]::list::lmap
namespace import [yclprefix]::list::lrange
namespace import [yclprefix]::list::lreplace
namespace import [yclprefix]::list::lreverse
namespace import [yclprefix]::list::lsort
namespace import [yclprefix]::list::order
namespace import [yclprefix]::list::pick
namespace import [yclprefix]::list::pop
namespace import [yclprefix]::list::prepend
namespace import [yclprefix]::list::randindex
namespace import [yclprefix]::list::rlindex
namespace import [yclprefix]::list::sl
namespace import [yclprefix]::list::slwild
namespace import [yclprefix]::list::split
namespace import [yclprefix]::list::tail
namespace import [yclprefix]::list::take
namespace import [yclprefix]::list::trim
namespace import [yclprefix]::list::unique
namespace import [yclprefix]::list::unpackvar
namespace import [yclprefix]::list::unset
namespace import [yclprefix]::list::zip
| > > > | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
interp alias {} [namespace current]::any {} [yclprefix] list any
interp alias {} [namespace current]::all {} [yclprefix] list all
interp alias {} [namespace current]::are {} [yclprefix] list are
interp alias {} [namespace current]::which {} [yclprefix] list which
namespace import [yclprefix]::list::add
namespace import [yclprefix]::list::addp
namespace import [yclprefix]::list::compare
namespace import [yclprefix]::list::complement
namespace import [yclprefix]::list::consume
namespace import [yclprefix]::list::dedent
namespace import [yclprefix]::list::dedent_exact
namespace import [yclprefix]::list::filter
namespace import [yclprefix]::list::head
namespace import [yclprefix]::list::join
namespace import [yclprefix]::list::lappend
namespace import [yclprefix]::list::lappend*
namespace import [yclprefix]::list::lindex
namespace import [yclprefix]::list::linsert
namespace import [yclprefix]::list::llength
namespace import [yclprefix]::list::lmap
namespace import [yclprefix]::list::lrange
namespace import [yclprefix]::list::lreplace
namespace import [yclprefix]::list::lreverse
namespace import [yclprefix]::list::lsort
namespace import [yclprefix]::list::order
namespace import [yclprefix]::list::pick
namespace import [yclprefix]::list::pop
namespace import [yclprefix]::list::prefix
namespace import [yclprefix]::list::prepend
namespace import [yclprefix]::list::randindex
namespace import [yclprefix]::list::rlindex
namespace import [yclprefix]::list::sl
namespace import [yclprefix]::list::slwild
namespace import [yclprefix]::list::split
namespace import [yclprefix]::list::subset
namespace import [yclprefix]::list::tail
namespace import [yclprefix]::list::take
namespace import [yclprefix]::list::trim
namespace import [yclprefix]::list::unique
namespace import [yclprefix]::list::unpackvar
namespace import [yclprefix]::list::unset
namespace import [yclprefix]::list::zip
|
| ︙ | ︙ | |||
182 183 184 185 186 187 188 189 190 191 192 193 194 195 |
lappend res item
}
return $res
} -cleanup [cleanup1] -result [sl {
one break {two three} four five
}]
test consume_break {} -body {
set list {one {two three} four five}
set res {}
consume item list {
if {$item eq {four}} break
lappend res item
| > > > > > > > > > > > > > > > > | 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 |
lappend res item
}
return $res
} -cleanup [cleanup1] -result [sl {
one break {two three} four five
}]
test complement {} -setup $setup1 -body {
set list2 $list1
lreplace list2 3 3
set complement [complement list2 list1]
lappend res complement
set complement [complement list1 list2]
lappend res complement
return $res
} -cleanup [cleanup1] -result [sl {
{} {\{\"\ }
}]
test consume_break {} -body {
set list {one {two three} four five}
set res {}
consume item list {
if {$item eq {four}} break
lappend res item
|
| ︙ | ︙ | |||
304 305 306 307 308 309 310 |
dedent res
expr {$res eq $original}
} -cleanup [cleanup1] -result 1
test filter {} -body {
set list {banana cucumbers {star fruit} kiwi}
| | > | 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 |
dedent res
expr {$res eq $original}
} -cleanup [cleanup1] -result 1
test filter {} -body {
set list {banana cucumbers {star fruit} kiwi}
filter list [are $list in [data fruits]]
return $list
} -cleanup [cleanup1] -result [sl {
banana {star fruit} kiwi
}]
test head {} -setup $setup1 -body {
head list1 {viis 001 01}
|
| ︙ | ︙ | |||
559 560 561 562 563 564 565 566 567 568 569 570 571 572 |
test pop_notenough_vars {} -body {
set list {one {two three} four five}
pop list var1 var2 var3 var4 var5
} -cleanup [cleanup1] -returnCodes 1 -result [sl {
{not enough items in list}
}]
test prepend {} -setup $setup1 -body {
prepend list1 one {two three} four
return $list1
} -cleanup [cleanup1] -result [sl {
one {two three} four
üks {kaks kolm} 020 "\{\" " neli " \t\n " 20 010 10 viis
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 |
test pop_notenough_vars {} -body {
set list {one {two three} four five}
pop list var1 var2 var3 var4 var5
} -cleanup [cleanup1] -returnCodes 1 -result [sl {
{not enough items in list}
}]
test prefix {} -setup $setup1 -body {
set list2 $list1
lrange list2 0 4
set prefix $list2
prefix prefix list1
lappend res prefix
set prefix $list1
prefix prefix list2
lappend res prefix
set list2 $list1
lrange list2 0 4
set prefix $list2
prefix list1
lappend res prefix
set prefix $list1
prefix list2
lappend res prefix
return $res
} -cleanup [cleanup1] -result [sl {
1 0 1 0
}]
test prepend {} -setup $setup1 -body {
prepend list1 one {two three} four
return $list1
} -cleanup [cleanup1] -result [sl {
one {two three} four
üks {kaks kolm} 020 "\{\" " neli " \t\n " 20 010 10 viis
|
| ︙ | ︙ | |||
612 613 614 615 616 617 618 619 620 621 622 623 624 625 |
set list {one,two,three,four}
split list ,
return $list
} -cleanup [cleanup1] -result [sl {
one two three four
}]
test tail {} -body {
set list {one {two three} four {five six}}
tail list {one {two three}}
return $list
} -cleanup [cleanup1] -result [sl {
four {five six}
| > > > > > > > > > > > > > > > > | 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 |
set list {one,two,three,four}
split list ,
return $list
} -cleanup [cleanup1] -result [sl {
one two three four
}]
test subset {} -setup $setup1 -body {
set list2 $list1
lreplace list2 3 3
set subset [subset list2 list1]
lappend res subset
set subset [subset list1 list2]
lappend res subset
return $res
} -cleanup [cleanup1] -result [sl {
1 0
}]
test tail {} -body {
set list {one {two three} four {five six}}
tail list {one {two three}}
return $list
} -cleanup [cleanup1] -result [sl {
four {five six}
|
| ︙ | ︙ |
Changes to packages/list/lib/object.tcl.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
#! /usr/bin/tclsh
package require {ycl proc}
[yclprefix] proc alias [yclprefix]::proc::alias
alias [yclprefix]::proc::checkargs
variable doc::.init {
args {
_ {}
list {
description {
the initial list value
}
default {
::lindex {}
}
process {
| > | > | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | < < < < < < < < < < < < | | > > > > > > > > > > > > | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
#! /usr/bin/tclsh
package require {ycl proc}
[yclprefix] proc alias [yclprefix]::proc::alias
alias [yclprefix]::proc::checkargs
variable doc::.init {
args {
_ {}
list {
description {
the initial list value
}
default {
::lindex {}
}
process {
$self $ list $list
}
}
}
}
proc .init {_ args} {
set self [$_ _]
$self .vars cursor
checkargs ${doc::.init} {*}$args
set cursor -1
return $self
}
.my .method .init
variable doc::advance {
description
advance the cursor value
}
proc advance {_ amount} {
$_ . .vars cursor list
set index [expr {$cursor + entier(amount)}]
$_ .cursor $index
}
.my .method advance
variable doc::cursor {
description
provides the cursor value
if $index is provided
sets the cursor value to $index
}
proc cursor {_ args} {
$_ . .vars cursor list
if {[llength $args]} {
lassign $args new
if {$new < -1 || $new > [::llength $list]} {
error [list {out of range} $new]
}
set cursor $new
}
return $cursor
}
.my .method cursor
proc has {_ item} {
$_ . .vars list
set res [lsearch -exact $list $item]
expr {$res >= 0}
}
.my .method has
proc next _ {
$_ . .vars cursor list
incr cursor
if {$cursor >= [::llength $list] } {
return -code break
}
::lindex $list $cursor
}
.my .method next
proc peek _ {
$_ . .vars cursor list
set idx [expr {$cursor + 1}]
if {$idx >= [::llength $list] } {
error finished
}
::lindex $list $idx
}
.my .method peek
proc value {_ args} {
$_ . .vars list
lset len [::length $args]
if {$len == 1} {
set list $args
} elseif {$len == 0} {
} else {
error [list {wrong # args}]
}
|
| ︙ | ︙ |
Changes to packages/list/pkgIndex.tcl.
1 2 | #! /bin/env tclsh | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 |
#! /bin/env tclsh
package ifneeded {ycl list} 2.0 [list apply {{dir} {
package require {ycl package}
[yclprefix]::package::source list $dir/lib/list.tcl
package provide {ycl list} 2.0
}} $dir]
package ifneeded {ycl list list} 1.0 [list apply {{dir} {
package require {ycl package}
package require {ycl shelf shelf}
set name [yclprefix]::list::list
|
| ︙ | ︙ |