emacs方言を使ってlispを学ぼうとしていますが、質問があります。リストにいくつかのメンバーがあり、その述語がfalseと評価されたとします。それらのメンバーなしで新しいリストを作成するにはどうすればよいですか?のようなもの{ A in L: p(A) is true }。Pythonにはフィルター関数がありますが、lispに同等のものはありますか?そうでない場合は、どうすればよいですか?
ありがとう
(require 'cl)これらの関数はCLパッケージに含まれているため、次のように使用する必要があります。
(remove-if-not #'evenp '(1 2 3 4 5))
これにより、引数からすべての偶数を含む新しいリストが返されます。
また、ルックアップしますdelete-if-not。これは同じことを行いますが、引数リストを変更します。
コード内でリストを頻繁に操作する場合は、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)
私は昨夜まったく同じものを探していて、 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.