You have a list with a bunch of items, but you want to have a copy of that list with some items removed.
filter, in PLT's standard library, allows you to filter a list based on a predicate.
> (require (lib "list.ss"))
> (filter odd? '(1 2 3 4 5 6 7 8 9 0))
(1 3 5 7 9)
> (filter string? '(14 "abc" cons "xyz" 23))
("abc" "xyz")
You can supply your own predicate, as well. Here we filter a list of numbers that are greater than some limit we've defined:
> (let ((limit 12))
(filter (lambda (x) (> x limit)) (map (lambda (n) (* n n)) '(1 2 3 4 5 6 7 8))))
(16 25 36 49 64)
PLT ships with a version of
filter in the
list.ss library. You can also use SRFI-1 for another version of the same function.
There are a few twists on this problem.
SRFI-1's
partition works like filter, except that it returns 2 lists, one with items that pass the filter, and the other with the rest of the items in the original list, e.g.
> (require (lib "1.ss" "srfi"))
> (filter string? '(14 "abc" cons "xyz" 23))
("abc" "xyz")
> (partition string? '(14 "abc" cons "xyz" 23))
("abc" "xyz")
(14 cons 23)
Also in
SRFI-1,
remove is the reverse of
filter, returning a new list without the items satisfying the predicate supplied. In addition, there are ! versions of all these functions to modify a list in-place.
Also,
SRFI-1's
filter-map is another twist on
filter, combining it with
map. It's like a
map that returns only the true values. Here we return the products of two lists, but only if both members of the lists are numbers:
> (filter-map (lambda (x y) (and (number? x) (number? y) (* x y))) '(a 1 b 3 c 7) '(cons 14 "abc" "xyz" 23 9))
(14 63)
If you know the item you want to remove, you can avoid writing a predicate by using
SRFI-1's
delete function:
> (delete 2 (list 1 3 5 7 9 2 4 6 8))
(1 3 5 7 9 4 6 8)
--
NoelWelsh - 02 Jun 2004
--
GordonWeakliem - 06 Aug 2004