2

関数は、シーケンスのany要素に対して関数(または述語)を評価し、述語がシーケンスのいずれかの要素に対してtrueを返す場合はtrueを返します。したがって

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

..nil以外を返し、

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

...nilを返します。

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が、それは実際にはそれが節約するよりも多くの費用がかかるかもしれません。

チップ?

4

3 に答える 3

5
(defun any (pred list)
  (while (and list (not (funcall pred (car list))))
    (pop list))
  (car list))
于 2012-04-06T22:10:46.303 に答える
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))
于 2012-04-06T21:30:02.063 に答える
1

おそらく、 http://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node145.htmlfind-ifで説明されているを使用できます。

それはあなたが望むことを正確に行うように聞こえます

(find-if 'stringp '(a "yes"))
"yes"
(find-if 'stringp '(a b))
nil
于 2012-04-06T19:47:24.907 に答える