(defun delete-nth (index seq)
(let ((element (nth index seq)))
(if element
(delete element seq)
seq)))
1 个赞
或者你直接找到 nth 位置以后, 先 split , 然后再 Join
(defun delete-nth (n list)
(append (subseq list 0 (1- n)) (nthcdr n list)))
@casouri 这个怎么样?
就是我说的先分成两半, 再把两个列表粘贴到一起.
2 个赞
这个挺好的 主要我想的是destructive的。(今天早上新学的词……)
分两半的思路主要是以后再读好懂一点, 要不是自己的代码隔几个月自己都要看半天.
哈哈哈,的确。每隔几个月看之前的代码像看💩一样
我试了试,好像不太行
(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)
我讨厌写 cdr, car, cdar, cadr 这种, 过几天, 每次读代码, 都要根据当前的表达式一层一层的数, 心累.
告诉你一个小技巧, google 的时候用 lisp blablabla , 不要用 elisp blabla, lisp 高手相对于 elisp 高手要多很多, 然后很多 lisp 的代码拷贝到 emacs 里面是可以直接运行的.
3 个赞
docstring写好的话,一般用的话也不用非得再看源码了。要是需要改可能就费点劲……
(defun nd (n list)
(let ((end (nthcdr (1+ n) list)))
(setf (nthcdr n list) end)
list))
改了。
这个挺好的,不过destructive的有没有可能?
比如
(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)
分支可以省略吧?
pop宏内部用的setq来搞,其实不是严格的destructive吧
(let* ((a '(1 2 3)) (b (cdr a))) (pop a) (eq b a)) ;; t
并不能
爲什麼0不能?
(defmacro nd (n exp)
(let ((b (gensym)))
`(let ((,b ,exp))
(setf (nthcdr ,n ,b) (nthcdr ,(1+ n) ,b))
,b)))
(setq foo '(1 2 3 4))
;; -> (1 2 3 4)
(nd 0 foo)
;; -> (2 3 4)
foo
;; -> (1 2 3 4)
因为
不可能破壞性去除一個列表的头。因為头沒了整个表也沒了。