假设我们有一个如下列表:
("These" "Are "Some" "Words")
,我们称之为listy
如何在列表中的每个项目上调用函数?
也许调用类似的函数:
(defun messager (somelist)
(interactive)
(message somelist)
)
运行功能:
(messager listy)
我希望在缓冲区中看到列表中每个项目的单独行。
不起作用的部分是循环或列表中的项目。
答案 0 :(得分:7)
使用
(mapc 'messager listy)
或
(dolist (item listy)
(messager item))
答案 1 :(得分:0)
现在,我要再次进行自我宣传:P但希望我能在路上传达一些有用的信息:
;; Here is what `dolist' expands to:
(dolist (item listy)
(messager item))
(identity
(catch (quote --cl-block-nil--)
(let ((--dolist-tail-- listy) item)
(while --dolist-tail--
(setq item (car --dolist-tail--))
(messager item)
(setq --dolist-tail-- (cdr --dolist-tail--))))))
;; And here is what `i-iterate' expands to:
(++ (for item in listy)
(messager item))
(let* ((--0 listy) item)
(while --0
(setq item (car --0) --0 (cdr --0))
(messager item)))
一些评论:dolist
将创建一个(catch ...)
块,无论是否存在条件退出,而i-iterate
只有在识别出此类条件退出时才会尝试执行此操作。通常,在(catch ...)
形式内执行代码要慢一些。
此外,dolist
会将代码包装成一个特殊的“块”(基本上只是对identity
函数的调用。这也是一种残缺,这是默认的,但并不总是需要。
现在,关于alist
的其他问题,您可以像这样使用loop
宏:
(loop for (key . value) in '((a . b) (c . d)) do
(message "key: %s -> value: %s" key value))
;; Which expands to:
(identity
(catch (quote --cl-block-nil--)
(let* ((--cl-var-- (quote ((a . b) (c . d)))) (value nil) (key nil))
(while (consp --cl-var--)
(setq value (car --cl-var--)
key (car (prog1 value (setq value (cdr value)))))
(message "key: %s -> value: %s" key value)
(setq --cl-var-- (cdr --cl-var--))) nil)))
;; Compared to i-iterate
(++ (for (key . value) in '((a . b) (c . d)))
(message "key: %s -> value: %s" key value))
;; Which expands to:
(let* ((--0 (quote ((a . b) (c . d)))) value key)
(while --0
(setq key (caar --0) value (cdar --0) --0 (cdr --0))
(message "key: %s -> value: %s" key value)))
在这种特殊情况下使用pop
是不合理的。同样地使用(catch ...)
块(因为没有条件退出)。
哦,以及图书馆的链接:http://code.google.com/p/i-iterate/:)
为此目的使用mapc
的好处和缺点:高阶函数与现有函数完美结合。所以,如果你已经有一个想要应用于每个元素 - 这可能是解决问题的最佳方法。但是,如果您要创建一个仅用于高阶函数的函数 - 那么它很少会得到回报,因为您将创建一个“冗余”实例,否则您可能会避免这种情况。情况并非总是如此,有时候,特别是与宏一起使用时,这可能是一个强大的工具,但就像你的情况一样,迭代似乎更适合。