40

emacs方言を使ってlispを学ぼうとしていますが、質問があります。リストにいくつかのメンバーがあり、その述語がfalseと評価されたとします。それらのメンバーなしで新しいリストを作成するにはどうすればよいですか?のようなもの{ A in L: p(A) is true }。Pythonにはフィルター関数がありますが、lispに同等のものはありますか?そうでない場合は、どうすればよいですか?

ありがとう

4

7 に答える 7

48

(require 'cl)これらの関数はCLパッケージに含まれているため、次のように使用する必要があります。

(remove-if-not #'evenp '(1 2 3 4 5))

これにより、引数からすべての偶数を含む新しいリストが返されます。

また、ルックアップしますdelete-if-not。これは同じことを行いますが、引数リストを変更します。

于 2010-02-10T06:58:43.723 に答える
24

コード内でリストを頻繁に操作する場合は、dash.elボイラープレート コードを記述して車輪を再発明するのではなく、最新の関数型プログラミング ライブラリを使用してください。リスト、ツリー、関数アプリケーション、およびフロー制御を操作するためのすべての機能を備えています。述語に一致するすべての要素を保持し、必要な他の要素を削除するには-filter:

(-filter (lambda (x) (> x 2)) '(1 2 3 4 5)) ; (3 4 5)

関心のある他の関数には-remove、 、-take-while、が含まれ-drop-whileます。

(-remove (lambda (x) (> x 2)) '(1 2 3 4 5)) ; (1 2)    
(-take-while (lambda (x) (< x 3)) '(1 2 3 2 1)) ; (1 2)
(-drop-while (lambda (x) (< x 3)) '(1 2 3 2 1)) ; (3 2 1)

素晴らしいのは、アナフォリック マクロdash.elをサポートしていることです。アナフォリック マクロは関数のように動作しますが、特殊な構文を使用してコードをより簡潔にすることができます。前の例のように、無名関数を引数として指定する代わりに、 s 式を記述してローカル変数の代わりに使用します。対応するアナフォリック マクロは、1 つではなく 2 つのダッシュで始まります。itx

(--filter (> it 2) '(1 2 3 4 5)) ; (3 4 5)
(--remove (> it 2) '(1 2 3 4 5)) ; (1 2)
(--take-while (< it 3) '(1 2 3 2 1)) ; (1 2)
(--drop-while (< it 3) '(1 2 3 2 1)) ; (3 2 1)
于 2014-08-03T16:32:31.277 に答える
19

私は昨夜まったく同じものを探していて、 EmacsWiki のElisp Cookbook出くわしました。Lists/Sequences のセクションには、フィルタリング技術が含まれており、これをmapcarおよびで行う方法を示していますdelq。自分の目的のためにコードを変更する必要がありましたが、元のコードは次のとおりです。

;; Emacs Lisp doesn’t come with a ‘filter’ function to keep elements that satisfy 
;; a conditional and excise the elements that do not satisfy it. One can use ‘mapcar’ 
;; to iterate over a list with a conditional, and then use ‘delq’ to remove the ‘nil’  
;; values.

   (defun my-filter (condp lst)
     (delq nil
           (mapcar (lambda (x) (and (funcall condp x) x)) lst)))

;; Therefore

  (my-filter 'identity my-list)

;; is equivalent to

  (delq nil my-list)

;; For example:

  (let ((num-list '(1 'a 2 "nil" 3 nil 4)))
    (my-filter 'numberp num-list))   ==> (1 2 3 4)

;; Actually the package cl-seq contains the functions remove-if and remove-if-not. 
;; The latter can be used instead of my-filter.
于 2010-02-10T08:40:51.583 に答える