lispelisp

Mapping a function over two lists in elisp


In common lisp I can do this:

(mapcar #'cons '(1 2 3) '(a b c))

=> ((1 . A) (2 . B) (3 . C))

How do I do the same thing in elisp? When I try, I get an error:

(wrong-number-of-arguments mapcar 3)

If elisp's mapcar can only work on one list at a time, what is the idomatic way to combine two lists into an alist?


Solution

  • You want mapcar*, which accepts one or more sequences (not just lists as in Common Lisp), and for one sequence argument works just like the regular mapcar.

    (mapcar* #'cons '(1 2 3) '(a b c))
    ((1 . A) (2 . B) (3 . C))
    

    And even if it weren’t defined, you could easily roll your own:

    (defun mapcar* (f &rest xs)
      "MAPCAR for multiple sequences"
      (if (not (memq nil xs))
        (cons (apply f (mapcar 'car xs))
          (apply 'mapcar* f (mapcar 'cdr xs)))))