Bill Wood william.wood3 at comcast.net
Thu Jan 4 11:46:53 CST 2007

```On Thu, 2007-01-04 at 11:23 -0500, sen1 at math.msu.edu wrote:
>
> Like
>    find_index, list_index, or locate_index
>
> Of course, the actual function could actually find many indices for various
> predicates.

>From the examples it seems clear that the desired functionality is to
return the list of indices of all occurrences of items satisfying the
predicate.  The Common Lisp built-in "position-if" returns the index of
only the left-most (right-most if :from-end is non-nil) occurrence, so
some code has to be written.  How about "all-positions-if" or
"all-positions"?  "positions-if" or "positions" might also be used, but
they could too easily be confused with (or fat-fingered into)
"position-if" or "position", and you might want those functions as well.

Here's a bare-bones CL function definition:

(defun all-positions-if (items pred)
(do ((i 0 (1+ i))
(xs items (cdr xs))
(acc '() (if (funcall pred (car xs)) (cons i acc) acc)))
((endp xs) (nreverse acc))))

Test runs:

* (all-positions-if '(2 1 3 3 5) #'(lambda (x) (= x 3)))
(2 3)
* (all-positions-if '(2 1 3 3 5) #'(lambda (x) (= x 33)))
NIL

(Don't forget, CL uses 0-based indexing; I guess maxima uses 1-based?)

If you like a more functional style, here's an alternative definition:

(defun all-positions-if (items pred)
(labels ((h (pr x)
(cons (1+ (car pr))
(if (funcall pred x)
(cons (car pr) (cdr pr))
(cdr pr)))))
(nreverse (cdr (reduce #'h items :initial-value (cons 0 '()))))))

-- Bill Wood

```