This is a read-only archive of lispforum.com. The forum was locked to new users and posts and is preserved here as static HTML from a database snapshot taken on 2019-09-07.

iterating through the same list with two indices

4 posts · 2615 views

I need to run through a list comparing each member to every member after that member for a condition. A very naiive approach would be:
(loop for i from 0 to (1- (length THE-LIST)) do
   (loop for j from (1+ i) to (1- (length THE-LIST)) do
      (test-the-items  (nth i THE-LIST) (nth j THE-LIST))
This is easily understood, but very ugly.

Another lispier, but probably just as ugly, way would be
(mapcar #'(lambda (item1)
                     (mapcar #'(lambda (item2) 
                                         (test-the-items item1 item2))
                                  (nthcdr (position item1 THE-LIST))))  THE-LIST)
Is there a cleaner way to do this?

Edit, after some more thinking, this:
    
(loop for i in THE-LIST do
	  (loop for j in (nthcdr (1+ (position i THE-LIST)) THE-LIST) do
                 (test-the-items i j))

Re: iterating through the same list with two indices

I don't think the solution with MAPCAR is ugly at all, it's only verbose, but lispy at the same time

Another option would be:
(loop for (elt1 . rest) on THE-LIST do
     (loop for elt2 in rest do
          (test-the-items elt1 elt2)))

Re: iterating through the same list with two indices

gugamilare wrote:I don't think the solution with MAPCAR is ugly at all, it's only verbose, but lispy at the same time

Another option would be:
(loop for (elt1 . rest) on THE-LIST do
     (loop for elt2 in rest do
          (test-the-items elt1 elt2)))
That dotted list is perfect, it is easy to understand and efficient. Thanks!

Re: iterating through the same list with two indices

Just a side note:
to (1- (length THE-LIST))
is equivalent to:
below (length THE-LIST)