Here is something similar I wrote a long time ago to be able to set or remove an atom from in a list. It's a lot more "brute force" and the speed of it will depend on the position of the element that we are trying to remove. also, there is a lot of overhead from the double reverse of the Add function.
(Defun Add ( ATM LST )
(Reverse (Cons ATM (Reverse LST)) )
)
(Defun SetNth ( IDX LST ITM / cnt return )
(SetQ cnt 0 )
(While (< cnt IDX)
(SetQ return (Add (Car LST) return)
LST (Cdr LST)
cnt (1+ cnt)
)
)
(SetQ return (Append (Add ITM return) (Cdr LST)) )
return
)
(Defun RemoveNth ( IDX LST / cnt return )
(SetQ cnt 0 )
(While (< cnt IDX)
(SetQ return (Add (Car LST) return)
LST (Cdr LST)
cnt (1+ cnt)
)
)
(SetQ return (Append return (Cdr LST)) )
return
)
It's very similar to ElpanovEvgeniy's solution, but he managed to get around the double reverse!
When n is less than 0 or greater than (length LST), the function of problem exist.such as:
_$ (remove-nth -3 '("a" "b" "c" d e d f g h d d d))
("b" "c" D E D F G H D D D)
_$ (remove-nth 18 '("a" "b" "c" d e d f g h d d d))
("a" "b" "c" D E D F G H D D D nil nil nil nil nil nil)
Here are my revised code:
;; 上面的函数有错误,所以修改后为:by 小李子
(Defun Remove-Nth-0 (IDX LST / cnt ret)
(if (and LST (>= IDX 0) (< IDX (length LST)))
(progn
(SetQ cnt 0)
(While (< cnt IDX)
(SetQ ret (Add (Car LST) ret)
LST (Cdr LST)
cnt (1+ cnt)
)
)
(SetQ ret (Append ret (Cdr LST)))
)
(setq ret LST)
)
ret
)