On Thu, 2007-01-04 at 11:23 -0500, sen1 at math.msu.edu wrote:
> How about a name more mnemonic about indices?
>
> 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