Що ж, якщо ви хочете скочувати свою власну, а не використовувати 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)))