映射函数(mapping function) 会将指定函数(注意:不能是 特殊形式或宏)应用于序列(如列表、向量或字符串)的每个元素(see 序列、数组与向量)。Emacs Lisp 提供了多个此类函数;本节介绍 mapcar、mapc、mapconcat 和 mapcan—— 这些函数用于遍历序列并执行映射操作。关于遍历符号表(obarray)中所有符号的 mapatoms 函数,See Definition of mapatoms;关于遍历哈希表中键值对的 maphash 函数,see Definition of maphash。
这些映射函数无法作用于字符表(char-table)—— 因为字符表是一种稀疏数组,其标称索引范围极大。若要适配字符表的稀疏特性进行遍历映射,需使用 map-char-table 函数(see 字符表)。
mapcar 会依次将 function 应用于 sequence 的每个元素,并返回由所有执行结果组成的列表。
参数 sequence 可以是除字符表(char-table)之外的任意类型序列;具体包括列表(list)、向量(vector)、布尔向量(bool-vector)或字符串(string)。返回结果始终为一个列表,且结果的长度与 sequence 的长度完全一致。例如:
(mapcar #'car '((a b) (c d) (e f)))
⇒ (a c e)
(mapcar #'1+ [1 2 3])
⇒ (2 3 4)
(mapcar #'string "abc")
⇒ ("a" "b" "c")
;; Call each function in my-hooks.
(mapcar 'funcall my-hooks)
(defun mapcar* (function &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 function (mapcar #'car args)) (apply #'mapcar* function ;; Recurse for rest of elements. (mapcar #'cdr args)))))
(mapcar* #'cons '(a b c) '(1 2 3 4))
⇒ ((a . 1) (b . 2) (c . 3))
该函数会将 function 应用于 sequence 的每个元素,行为与 mapcar 类似;但与 mapcar 收集结果到列表中不同的是,它会通过修改(借助 nconc 函数;see 重排列表的函数)这些结果(要求结果必须是列表),最终返回一个包含所有结果元素的单一列表。和 mapcar 一样,sequence 可以是除字符表(char-table)之外的任意类型序列。
;; Contrast this: (mapcar #'list '(a b c d)) ⇒ ((a) (b) (c) (d)) ;; with this: (mapcan #'list '(a b c d)) ⇒ (a b c d)
mapc 的行为与 mapcar 类似,区别在于 function 仅用于产生副作用 — 其返回值会被忽略,不会被收集到列表中。mapc 的返回值始终是 sequence 本身。
mapconcat 会将 function 应用于 sequence 的每个元素;函数执行结果(必须是字符序列,如字符串、向量或列表)会被拼接为一个单一字符串作为返回值。在每两个结果序列之间,mapconcat 会插入 separator 中的字符 ——separator 也必须是字符串、字符向量或字符列表;若 separator 为 nil,则会被视作空字符串。See 序列、数组与向量。
参数 function 必须是一个可接收单个参数、且返回字符序列(字符串、向量或列表)的函数。参数 sequence 可以是除字符表(char-table)之外的任意类型序列;具体包括列表、向量、布尔向量(bool-vector)或字符串。
(mapconcat #'symbol-name
'(The cat in the hat)
" ")
⇒ "The cat in the hat"
(mapconcat (lambda (x) (format "%c" (1+ x)))
"HAL-8000")
⇒ "IBM.9111"