Argument | Meaning | Default |
:test | Two-argument function used to compare item (or value extracted by :key function) to element. | EQL |
:key | One-argument function to extract key value from actual sequence element. NIL means use element as is. | NIL |
:start | Starting index (inclusive) of subsequence. | 0 |
:end | Ending index (exclusive) of subsequence. NIL indicates end of sequence. | NIL |
:from-end | If true, the sequence will be traversed in reverse order, from end to start. | NIL |
:count | Number indicating the number of elements to remove or substitute or NIL to indicate all (REMOVE and SUBSTITUTE only). | NIL |
For each of the functions just discussed, Common Lisp provides two -IF
appended. These functions count, find, remove, and substitute elements of the sequence for which the function argument returns true. The other set of variants are named with an -IF-NOT
suffix and count, find, remove, and substitute elements for which the function argument does
(count-if #'evenp #(1 2 3 4 5)) ==> 2
(count-if-not #'evenp #(1 2 3 4 5)) ==> 3
(position-if #'digit-char-p 'abcd0001') ==> 4
(remove-if-not #'(lambda (x) (char= (elt x 0) #f))
#('foo' 'bar' 'baz' 'foom')) ==> #('foo' 'foom')
According to the language standard, the -IF-NOT
variants are deprecated. However, that deprecation is generally considered to have itself been ill-advised. If the standard is ever revised, it's more likely the deprecation will be removed than the -IF-NOT
functions. For one thing, the REMOVE-IF-NOT
variant is probably used more often than REMOVE-IF
. Despite its negative-sounding name, REMOVE- IF-NOT
is actually the positive variant—it returns the elements that
The -IF
and -IF-NOT
variants accept all the same keyword arguments as their vanilla counterparts except for :test
, which isn't needed since the main argument is already a function.[126] With a :key
argument, the value extracted by the :key
function is passed to the function instead of the actual element.
(count-if #'evenp #((1 a) (2 b) (3 c) (4 d) (5 e)) :key #'first) ==> 2
(count-if-not #'evenp #((1 a) (2 b) (3 c) (4 d) (5 e)) :key #'first) ==> 3
(remove-if-not #'alpha-char-p
#('foo' 'bar' '1baz') :key #'(lambda (x) (elt x 0))) ==> #('foo' 'bar')
The REMOVE
family of functions also support a fourth variant, REMOVE-DUPLICATES
, that has only one required argument, a sequence, from which it removes all but one instance of each duplicated element. It takes the same keyword arguments as REMOVE
, except for :count
, since it always removes all duplicates.
(remove-duplicates #(1 2 1 2 3 1 2 3 4)) ==> #(1 2 3 4)
A handful of functions perform operations on a whole sequence (or sequences) at a time. These tend to be simpler than the other functions I've described so far. For instance, COPY-SEQ
and REVERSE
each take a single argument, a sequence, and each returns a new sequence of the same type. The sequence returned by COPY-SEQ
contains the same elements as its argument while the sequence returned by REVERSE
contains the same elements but in reverse order. Note that neither function copies the elements themselves—only the returned sequence is a new object.
The CONCATENATE
function creates a new sequence containing the concatenation of any number of sequences. However, unlike REVERSE
and COPY-SEQ
, which simply return a sequence of the same type as their single