我对 Common Lisp 场景非常陌生,我似乎无法找到一种快速方法来从列表中获取第 n 个元素并同时将其从所述列表中删除。我已经做到了,但它并不漂亮,我真正想要的是类似“pop”的东西,但采用了第二个参数:
(setf x '(a b c d))
(setf y (popnth 2 x))
; x is '(a b d)
; y is 'c
我非常确定“popnth”必须是一个宏,以防参数为 0 并且它必须表现得像“pop”。
编辑:这是我的第一个版本:
(defmacro popnth (n lst)
(let ((tempvar (gensym)))
`(if (eql ,n 0)
(pop ,lst)
(let ((,tempvar (nth ,n ,lst)))
(setf (cdr (nthcdr ,(- n 1) ,lst)) (nthcdr ,(+ n 1) ,lst))
,tempvar))))
像这样的事情:
删除列表中的第 n 个元素:
(defun remove-nth (list n)
(remove-if (constantly t) list :start n :end (1+ n)))
不断地 http://www.lispworks.com/documentation/HyperSpec/Body/f_cons_1.htm返回一个函数,该函数始终返回其参数。
作为接受一个宏place http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_p.htm#place, using 定义-修改-宏 http://www.lispworks.com/documentation/HyperSpec/Body/m_defi_2.htm:
(define-modify-macro remove-nth-f (n) remove-nth "Remove the nth element")
POP-NTH
(defmacro pop-nth (list n)
(let ((n-var (gensym)))
`(let ((,n-var ,n))
(prog1 (nth ,n-var ,list)
(remove-nth-f ,list ,n-var)))))
Example:
CL-USER 26 > (defparameter *list* (list 1 2 3 4))
*LIST*
CL-USER 27 > (pop-nth *list* 0)
1
CL-USER 28 > *list*
(2 3 4)
CL-USER 29 > (pop-nth *list* 2)
4
CL-USER 30 > *list*
(2 3)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)