I would like to do:
(mapcar #'assoc '(a s) '((a . b) (c . d) (s . f)))
and have it return
((A . B) (S . F))
Which seems pretty reasonable, considering (assoc 'a '((a . b) (c . d) (s . f)))
returns (A . B)
and (assoc 's '((a . b) (c . d) (s . f)))
returns (S . F)
. But alas it does not work:
*** - ASSOC: A is not a list
The following restarts are available:
ABORT :R1 Abort main loop
Any thoughts?
When used with two lists, mapcar
applies the function pair-wise to the lists (and with three lists it applies them triple-wise etc.). So
(mapcar #'assoc '(a s) '((a . b) (c . d) (s . f)))
is the same as
( (assoc 'a (a . b)) (assoc 's (c . d)) )
(when used with lists of different length, mapcar
uses the size of the smallest list). To get what you want, you should do:
(mapcar (lambda (x) (assoc x '((a . b) (c . d) (s . f)))) '(a s))
We need another list level. The second argument should be a list of assoc lists.
CL-USER > (mapcar #'assoc '(a s) '(((a . b) (c . d) (s . f))))
((A . B))
But the second argument is only one element long. Now we can use a trick and make it a circular list:
CL-USER > (mapcar #'assoc '(a s) '#1=(((A . B) (C . D) (S . F)) . #1#))
((A . B) (S . F))
If we construct a circular list for the second argument, then it works.
As a function:
(defun circular (list)
(if (null list)
list
(setf (cdr (last list)) list)))
CL-USER > (mapcar #'assoc '(a s) (circular '(((a . b) (c . d) (s . f)))))
((A . B) (S . F))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With