Ну, если вы хотите бросить свой собственный вместо использования cl-position
, и вы не хотите проходить дважды (используя length
) ...
(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. Тем не менее, у него есть такая разница в поведении, которая вам может понадобиться, а может и не понадобиться: она работает также для автомобилей с пунктирным списком. Таким образом, он корректно возвращает позицию, вместо того, чтобы выдавать ошибку, для сексов, таких как (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)))