回答:
(cl-position 2 '(6 7 8 2 3 4)) ;; => 3
(Emacs 24.3より前は、Emacsに含まれているposition
libraryの関数を使用してくださいcl.el
。)
:test
キーワードを使用して、比較関数を指定できます。
(cl-position "bar" '("foo" "bar" "baz") :test 'equal) ;; => 1
(cl-position '(1 2) '((3) (5 6) (1 2) nil) :test 'equal) ;; => 2
Emacs Common Lispエミュレーションマニュアル
dash.el
これを行うことができる機能があります: -elem-index
(-elem-index 2 '(6 7 8 2 3 4)) ;; => 3
(-elem-index "bar" '("foo" "bar" "baz")) ;; => 1
(-elem-index '(1 2) '((3) (5 6) (1 2) nil)) ;; => 2
これは、Emacsのに含まれていますが、Emacsのユーザーの多くは、すでにそれがインストールされています(それはの依存関係だprojectile
、flycheck
とsmartparens
それを報道のトンを与えます、)。
さて、を使用する代わりに独自のロールcl-position
を行いたい場合、および(を使用してlength
)2回トラバースしたくない場合...
(defun nth-elt (element xs)
"Return zero-indexed position of ELEMENT in list XS, or nil if absent."
(let ((idx 0))
(catch 'nth-elt
(dolist (x xs)
(when (equal element x) (throw 'nth-elt idx))
(setq idx (1+ idx)))
nil)))
これは、古いEmacsバージョンでも有効です。ただし、この動作の違いがあり、必要な場合とそうでない場合があります。点線リストの車に対しても機能します。つまり、などのsexpsに対して、エラーを発生させる代わりに正しく位置を返します(nth-elt 'c '(a b c . d))
。
不適切なリストに対して常にエラーを発生させたい場合は、そのケースをチェックする必要があります。この場合、常にリストの最後まで移動する必要があります。
(defun nth-elt (element xs)
"Return zero-indexed position of ELEMENT in list XS, or nil if absent."
(let ((idx 0))
(when (atom (cdr (last xs))) (error "Not a proper list"))
(catch 'nth-elt
(dolist (x xs)
(when (equal element x) (throw 'nth-elt idx))
(setq idx (1+ idx)))
nil)))
それは書くのが簡単な関数であることが判明しましたが、それほど効率的ではないかもしれません:
(defun nth-elt (elt list)
"Return element number of ELT in LIST."
(let ((loc (length (member elt list))))
(unless (zerop loc)
(- (length list) loc))))
(nth-elt 'c '(a b c d)) ; => 2
(nth-elt 'f '(a b c d)) ; => nil
もちろん、組み込みのソリューションが存在する場合はそれを好むでしょう。