Question: List position mapping in common lisp


List position mapping in common lisp

Answers 1
Added at 2016-12-28 21:12

I have 3 lists, where the first 2 lists have the same size and the third one is a sublist of the first. Lets say list1 is '(X Y Z W), list2 is '(1 2 3 4) and list3 is '(X Z) I need to get as result a sublist of the second one without the positions missing in list3 from list1, so in this case the result should be (1 3).

To get the position on an element I can write something like this:

    (position 'Z
      '(X Y Z W)
      :test #'equal)

That will return the 0 based position of the element. But I'm not sure about how to continue my function..

nr: #1 dodano: 2016-12-28 22:12

Here there are two possibile solutions, the first is a quadratic one that uses primitive functions:

(defun position-map (l1 l2 l3)
  (let ((pairs (pairlis l1 l2)))
    (mapcar (lambda (x) (cdr (assoc x pairs))) l3)))

(position-map '(x y z w) '(1 2 3 4) '(x z)) ;; => (1 3)

First we create a list with pairs formed by consing the elements of the two lists, then we scan the third list, by getting only the elements of the pairs that have the car equal to an element of the third list. This method works only if the elements in the first list are all different.

The second solution, linear, uses iteration, and allows also repeated elements in the first list, (but it works only if the elements of the third list are ordered as the elements of the first list):

(defun position-map (l1 l2 l3)
     for x in l1
     for y in l2
     when (eql x (car l3)) 
     collect y
     and do (pop l3)))
Source Show
◀ Wstecz