Common Lisp有一些功能。我如何写一些或任何elisp?

时间:2012-04-06 18:52:55

标签: emacs map elisp

any函数将评估序列元素的函数(或谓词),如果谓词对序列的任何元素返回true,则返回true。因此

(any `stringp `(42 t "yes" nil))

..将返回非零,

(any `stringp `(42 t nil 89))

...将返回零。

我认为CL模块中有some函数,但我不想使用它。

使用mapc编写一个简单的实现很容易:

(defun my-any (predicate sequence)
  "Return true if PREDICATE is true of any element of SEQUENCE.
If so, return the first non-nil value returned by PREDICATE.
"
  (let (result)
    (mapc '(lambda (elt)
             (or result
                 (setq result (funcall predicate elt))))
          sequence)
    result))

但是,任何人都可以提供优化或改进吗?是否有更快或更清洁或更惯用的elisp方式来做到这一点?特别是当第一个序列触发时,停止映射序列的最佳方法是什么?我可以“展开”mapc,但这是最好的方法吗?

我想我可以使用catch,但实际上可能会花费更多费用。

提示?

3 个答案:

答案 0 :(得分:5)

(defun any (pred list)
  (while (and list (not (funcall pred (car list))))
    (pop list))
  (car list))

答案 1 :(得分:2)

至少你可以在谓词为真时提前终止。像下面的东西。

 (defun my-any (predicate sequence)
  "Return true if PREDICATE is true of any element of SEQUENCE.
If so, return the first non-nil value returned by PREDICATE.
"
  (catch 'looking
    (mapc '(lambda (elt)
             (if (funcall predicate elt) (throw 'looking t)))
          sequence)
    nil))

答案 2 :(得分:1)

您可以使用http://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node145.html

中描述的find-if

听起来它完全符合您的要求

(find-if 'stringp '(a "yes"))
"yes"
(find-if 'stringp '(a b))
nil