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

Higher-Order Function Variants

For each of the functions just discussed, Common Lisp provides two higher-order function variants that, in the place of the item argument, take a function to be called on each element of the sequence. One set of variants are named the same as the basic function with an -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 not return true.

(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 do satisfy the predicate.[125]

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)

Whole Sequence Manipulations

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

Вы читаете Practical Common Lisp
Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату