Path: utzoo!mnetor!uunet!seismo!sundc!pitstop!sun!decwrl!labrea!jade!ucbvax!sdcsvax!ucsdhub!hp-sdd!hplabs!otter!kers From: kers@otter.HP.COM (Christopher Dollin) Newsgroups: comp.lang.lisp Subject: Filtering Vectors in CL Question Message-ID: <1350001@otter.HP.COM> Date: 17 Dec 87 10:59:17 GMT Organization: hplabs-brc Bristol,UK. Lines: 46 I have a query that has arisen out of local comparisons of Common Lisp and Pop11. What is the idiomatic and efficent way in CL to filter a vector; that is, to make a new vector from an existing vector, containing only those elements that satisfy some patameter predicate, and preserving the order? The best I can think of is (defun filterv (v p) (let ( (vv (make-array (length v) :fill-pointer 0)) ) (dotimes (i (length v)) (if (funcall (p (aref v i))) (vector-push vv (aref v i)) ) ) vv ) ) which seems to be rather ham-fisted, especially since it wastes space allocating an over-sized vector (if p actually removes any elements) and delivers an array with a fill-pointer, which may not be what you want (copying to a simple vector may also not be what you want, as you've now wasted space TWICE!). What's the nice way? [Note: one Pop11 solution is define filter( v, p ); lvars v, procedure p; {% appdata ( v, procedure ( x ); lvars x; if p( x ) then x endif endprocedure ) %} enddefine; which makes a vector out of all the elements in v that satisfy p, generates no garbage, and runs acceptably fast]. Regards, Kers | "Why Lisp if you can talk Poperly?"