[SS] 29Oct2004: '''filter''' is a very useful function in [functional programming], that given a list and a predicate (a function with arity of one, returing true or false) creates a new list which contains only the members of the original list meeting the predicate (in the same order they appeared). I plan to submit a TIP for the addition of this function together with [map in functional programming]. The following is an implementation for Tcl, with this command structure: filter var list expr Some usage example: % filter x {1 2 3 4 5 6 7 8 9} {$x > 4} 5 6 7 8 9 % filter x {1 2 3 4 5 6 7 8 9} {$x % 3} 1 2 4 5 7 8 % filter x {1 2 3 4 5 6 7 8 9} {($x % 3) == 0} 3 6 9 % filter x [list a b {} c d e {} {} f g] {[llength $x]} a b c d e f g Do you need filter? If you can see the following pattern in your code, you need it: set res {} foreach x $list { if {[foobar $x]} { lappend res $x } } use $res Finally the (very simple) code: proc filter {fvar flist fexpr} { upvar 1 $fvar var set res {} foreach var $flist { set varCopy $var if {[uplevel 1 [list expr $fexpr]]} { lappend res $varCopy } } return $res } ---- [RS] would prefer an argument sequence with the list in the end: filter x {$x > 4} $list so the second and third argument, which form a [lambda], are left together. ---- [SS] Indeed, it's not clear what's the best. I like more what you proposed from an aesthetic point of view, but to have the same arguments order as map and [foreach] can be a good point. There is another option too: filter $list x {$x > 4} that sounds to me slightly better. ---- '''Duoas''' writes his version proc lfilter {ls varName script} upvar 1 $varName var set result {} foreach var $ls val $ls { if {[uplevel 1 eval $script]} { lappend result $val } } return $result } and his motive (no expr) % set mixed {1 abc 2.5 twelve Annie -3 0} % lfilter $mixed x {string is double -strict $x} 1 2.5 -3 0 Hope this helps. [AM] (21 june 2006) But that would fail in circumstances where a numeric conditions is needed - "$x > 4" would need to become "expr {$x > 4}", not a pleasant user requirement, IMO ---- True, but I'm still not so sure I'm convinced either way. I don't like being constrained. In any case, with the advent of [apply] in Tcl 8.5, we can use true lambdas instead of the versions we've seen so far: proc ::filter {predicate ls} { set result {} foreach el $ls { if {[eval apply [list $predicate] $el]} { lappend result $el } } return $result } This version is particularly capable because you can choose between lambdas taking each element in the list as a whole or as individual arguments: % filter {{a b} {expr {$a == $b}}} {{2 2} {3 -7} {42 9} {7 7}} {2 2} {7 7} % filter {args {expr {[llength $args] == 2}}} {one {two words} only one {three words here} {two again}} {two words} {two again} 01-05-2007 Duoas ---- [RS] Again, here a version that uses [{*}]: proc ::filter {predicate ls} { set result {} foreach el $ls { if [apply $predicate {*}$el] {lappend result $el} } return $result } ---- [Category Algorithm]|[Category Functional Programming]