循环Emacs列表中的项目

时间:2013-01-11 21:14:54

标签: list function emacs

假设我们有一个如下列表:

("These" "Are "Some" "Words"),我们称之为listy

如何在列表中的每个项目上调用函数?

也许调用类似的函数:

(defun messager (somelist) 
 (interactive)
 (message somelist)
)

运行功能:

(messager listy)

我希望在缓冲区中看到列表中每个项目的单独行。

不起作用的部分是循环或列表中的项目。

2 个答案:

答案 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的好处和缺点:高阶函数与现有函数完美结合。所以,如果你已经有一个想要应用于每个元素 - 这可能是解决问题的最佳方法。但是,如果您要创建一个仅用于高阶函数的函数 - 那么它很少会得到回报,因为您将创建一个“冗余”实例,否则您可能会避免这种情况。情况并非总是如此,有时候,特别是与宏一起使用时,这可能是一个强大的工具,但就像你的情况一样,迭代似乎更适合。