position, position-if, position-if-not
position, position-if, position-if-not Function
Syntax:
position item sequence &key from-end test test-not start end key → position
position-if predicate sequence &key from-end start end key → position
position-if-not predicate sequence &key from-end start end key → position
Arguments and Values:
item—an object.
sequence—a proper sequence.
predicate—a designator for a function of one argument that returns a generalized boolean.
from-end—a generalized boolean. The default is false.
test—a designator for a function of two arguments that returns a generalized boolean. test-not—a designator for a function of two arguments that returns a generalized boolean.
start, end—bounding index designators of sequence. The defaults for start and end are 0 and nil, respectively.
key—a designator for a function of one argument, or nil.
position—a bounding index of sequence, or nil.
Description:
position, position-if, and position-if-not each search sequence for an element that satisfies the test.
The position returned is the index within sequence of the leftmost (if from-end is true) or of the rightmost (if from-end is false) element that satisfies the test; otherwise nil is returned. The index returned is relative to the left-hand end of the entire sequence, regardless of the value of start, end, or from-end.
Examples:
(position #\a "baobab" :from-end t) → 4
(position-if #’oddp ’((1) (2) (3) (4)) :start 1 :key #’car) → 2
(position 595 ’()) → NIL
(position-if-not #’integerp ’(1 2 3 4 5.0)) → 4
Exceptional Situations:
Should be prepared to signal an error of type type-error if sequence is not a proper sequence.
See Also:
find, Section 3.6 (Traversal Rules and Side Effects)
Notes:
The :test-not argument is deprecated.
The function position-if-not is deprecated.
searchExpanded Reference: position, position-if, position-if-not
Finding the index of an element
position returns the zero-based index of the first matching element, or NIL if not found.
(position 'c '(a b c d e))
=> 2
(position #\l "hello")
=> 2
(position 99 '(1 2 3))
=> NIL
Finding a position by predicate
position-if returns the index of the first element satisfying the predicate.
(position-if #'evenp '(1 3 5 2 7))
=> 3
(position-if #'digit-char-p "abc123")
=> 3
Searching from the end
With :from-end t, the position of the rightmost matching element is returned. The index is still relative to the start of the sequence.
(position #\a "banana")
=> 1
(position #\a "banana" :from-end t)
=> 5
Using :key to search by a derived value
(position 3 '((a 1) (b 2) (c 3)) :key #'second)
=> 2
(position-if #'oddp '((1 a) (2 b) (3 c)) :start 1 :key #'car)
=> 2
Restricting the search range
The :start and :end keywords limit the search, but the returned index is always relative to the beginning of the entire sequence.
(position #\o "hello world" :start 5)
=> 7
Practical example: splitting a string
position is often used to locate delimiters for parsing.
(let* ((str "key=value")
(pos (position #\= str)))
(values (subseq str 0 pos)
(subseq str (1+ pos))))
=> "key"
=> "value"