question about sublists



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