# [已解决] 怎么改进delete-nth？

``````(defun delete-nth (index seq)
"Delete the INDEX th element of SEQ.
Return result sequence, SEQ is modified."
(if (equal index 0)
(progn
(setcar seq (car (cdr seq)))
(setcdr seq (cdr (cdr seq))))
(setcdr (nthcdr (1- index) seq) (nthcdr (1+ index) seq))))
``````

(delete (nth index seq) seq) 可以不?

``````(defun nd (n list)
(let ((end (nthcdr (1+ n) list)))
(setf (nthcdr n list) nil)
(nconc list end)))
``````

delete会把所有equal的元素都删掉，

``````(setq my-seq '(1 1 1 2 3 4))
(setq my-seq (delete (nth 0 my-seq) my-seq))
my-seq
;=> (2 3 4)
``````
1 个赞
``````(defun delete-nth (index seq)
(let ((element (nth index seq)))
(if element
(delete element seq)
seq)))
``````
1 个赞

``````(defun delete-nth (n list)
(append (subseq list 0 (1- n)) (nthcdr n list)))
``````

@casouri 这个怎么样?

2 个赞

``````(defun nd (n list)
(let ((end (nthcdr (1+ n) list)))
(setf (nthcdr n list) nil)
(nconc list end)))
;=> nd
(setq my-seq '(1 1 1 2 3 4))
;=> (1 1 1 2 3 4)
(nd 0 my-seq)
;=> (1 1 2 3 4)
my-seq
;=> (1 1 1 2 3 4)
``````

3 个赞

docstring写好的话，一般用的话也不用非得再看源码了。要是需要改可能就费点劲……

``````(defun nd (n list)
(let ((end (nthcdr (1+ n) list)))
(setf (nthcdr n list) end)
list))
``````

``````(setq my-seq '(1 2 3 4))
;=> (1 2 3 4)

(delete-nth 0 my-seq)
;=> (3 4)

my-seq
;=> (2 3 4)
``````

``````(defmacro nd (n exp)
(if (zerop n)
`(progn
(pop ,exp)
,exp)
`(progn
(setf (nthcdr ,n ,exp) (nthcdr ,(1+ n) ,exp))
,exp)))
``````
1 个赞

`(zerop n)` 分支可以省略吧？