Next: , Previous: , Up: Functions and Commands   [Contents][Index]


17.6 Mapping Functions

A mapping function applies a given function to each element of a list or other collection. SXEmacs Lisp has several such functions; mapcar and mapconcat, which scan a list, are described here. See Creating Symbols, for the function mapatoms which maps over the symbols in an obarray.

Mapping functions should never modify the sequence being mapped over. The results are unpredictable. If in-place modification is explicitly what you want use the special function mapc-inplace.

Function: mapcar function sequence

mapcar applies function to each element of sequence in turn, and returns a list of the results.

The argument sequence can be any kind of sequence; that is, a list, a dllist, a vector, a bit vector, or a string. The result is always a list. The length of the result is the same as the length of sequence.

For example:
(mapcar 'car '((a b) (c d) (e f)))
     ⇒ (a c e)
(mapcar '1+ [1 2 3])
     ⇒ (2 3 4)
(mapcar 'char-to-string "abc")
     ⇒ ("a" "b" "c")
;; Call each function in my-hooks.
(mapcar 'funcall my-hooks)
(defun mapcar* (f &rest args)
  "Apply FUNCTION to successive cars of all ARGS.
Return the list of results."
  ;; If no list is exhausted,
  (if (not (memq 'nil args))
      ;; apply function to CARs.
      (cons (apply f (mapcar 'car args))
            (apply 'mapcar* f
                   ;; Recurse for rest of elements.
                   (mapcar 'cdr args)))))
(mapcar* 'cons '(a b c) '(1 2 3 4))
     ⇒ ((a . 1) (b . 2) (c . 3))
Function: mapconcat function sequence separator

mapconcat applies function to each element of sequence: the results, which must be strings, are concatenated. Between each pair of result strings, mapconcat inserts the string separator. Usually separator contains a space or comma or other suitable punctuation.

The argument function must be a function that can take one argument and return a string. The argument sequence can be any kind of sequence; that is, a list, a vector, a bit vector, or a string.

(mapconcat 'symbol-name
           '(The cat in the hat)
           " ")
     ⇒ "The cat in the hat"
(mapconcat (function (lambda (x) (format "%c" (1+ x))))
           "HAL-8000"
           "")
     ⇒ "IBM.9111"

In case the result is of minor importance, or the mapping function works by side-effect somehow you can prevent elisp from gathering the results. This will save you some time and memory.

Function: mapc function sequence

Apply function to each element of sequence. sequence may be a list, a dllist, a vector, a bit vector, or a string. This function is like mapcar but does not accumulate the results, which is more efficient if you do not use the results.

The difference between mapc and mapc-internal is that mapc supports all the spiffy Common Lisp arguments. You should normally use mapc.

(let ((all-prime-p t) ;; all numbers are assumed to be prime initially
      (list-of-numbers '(2 3 5 7 11 13)))
  (mapc #'(lambda (x)
            (when (and all-prime-p (not (primep x))
              (setq all-prime-p nil))))
        list-of-numbers)
  all-prime-p)
  ⇒ t
(let ((all-prime-p t) ;; all numbers are assumed to be prime initially
      (list-of-numbers '(2 4 6 8 10 13)))
  (mapc #'(lambda (x)
            (when (and all-prime-p (not (primep x))
              (setq all-prime-p nil))))
        list-of-numbers)
  all-prime-p)
  ⇒ nil

However, if you plan to use mapc with mapping functions which modify the current element of the sequence being mapped over by side-effect, don’t do it! The safer way is to use mapc-inplace which is even faster and less memory intensive than mapc.

Function: mapc-inplace function sequence

Apply function to each element of sequence and replace the element with the result. Return the (destructively) modified sequence.

At the moment, sequence can be a list, a dllist, a vector, a bit-vector, or a string.

Containers with type restrictions – strings or bit-vectors here – cannot handle all results of function. In case of bit-vectors, if the function yields nil or 0 the current bit is set to 0, if the function yields anything else, the bit is set to 1. Similarly in the string case any non-char result of function sets the currently processed character to ^@ (octal value: 000).

;; replace the elements of a list by the next-prime number
(let ((list-of-numbers '(22 59 104 193)))
  (mapc-inplace #'next-prime list-of-numbers)
  list-of-numbers)
  ⇒ (23 61 107 197)
;; replace a vector of lisp objects by their hash-value
(let ((vec-of-objects [22 foobar "string" nil]))
  (mapc-inplace #'sxhash vec-of-objects)
  vec-of-objects)
  ⇒ [45 912820644 212821792 912999036]

Next: , Previous: , Up: Functions and Commands   [Contents][Index]