我正在尝试用elisp实现我自己的深度复制例程(因为像(setq newlist oldlist)这样的东西似乎只提供浅层复制,而(copy-sequence newlist oldlist)仍然会让newlist暴露在oldlist元素的任何更改中)
此外,如果有一个函数可以做我想要的事情,我就没有机会找到它。
我的函数的定义是:
(defun deep-copy (iList oList)
(setq oList (car iList))
(setq counter (- (length iList) 1))
(setq iList (cdr iList))
(while (> counter 0)
(setq oList (cons oList (car iList)))
(setq iList (cdr iList))
(setq counter (- counter 1) )))之后,对于(1 2 3 4 5 6)的iList,oList恰好有:(((((1 . 2) . 3) . 4) . 5) . 6),即嵌套列表。
我尝试过引用,反引用,使用append,在(cons # #)中切换oList和(car iList)的顺序,用谷歌搜索解决方案,但我没有运气(要么是错误,要么是垃圾)。
除了任何关于已经存在的可以做我想做的事情的函数的欢迎评论,在代码中有弱点的地方(我是一个elisp新手),有人能告诉我如何正确地将元素添加到现有的列表中吗?
示例往往是以下形式的变体:(cons 'pine '(fir oak maple)),其中'(fir oak maple)是某个硬编码列表
编辑:在过去的两个小时里,我一直在与自己作斗争(自从我在调用函数中注释掉了oList,并且我一直在引用它的一个旧版本)。无论如何,交换oList和(car iList),然后在结尾处反转似乎是有效的(但肯定有更好的方法!?)即
(defun deep-copy (iList)
(setq oList nil )
(setq counter (- (length iList) 1))
(while (>= counter 0)
(setq oList (cons (car iList) oList) )
(setq iList (cdr iList) )
(setq counter (- counter 1) ))
(reverse oList)
)发布于 2013-06-03 04:03:01
使用copy-tree (为方便起见,示例假定您使用required cl,但copy-tree本身并不需要它):
elisp> (setq list1 '(((1 2) (3 4)) 5 (6)))
(((1 2)
(3 4))
5
(6))
elisp> (setq list2 (copy-sequence list1))
(((1 2)
(3 4))
5
(6))
elisp> (setf (caar list2) 1)
1
elisp> list2
((1
(3 4))
5
(6))
elisp> list1
((1
(3 4))
5
(6))
elisp> (setq list1 '(((1 2) (3 4)) 5 (6)))
(((1 2)
(3 4))
5
(6))
elisp> (setq list2 (copy-tree list1))
(((1 2)
(3 4))
5
(6))
elisp> (setf (caar list2) 1)
1
elisp> list1
(((1 2)
(3 4))
5
(6))
elisp> list2
((1
(3 4))
5
(6))我建议您通读Emacs:C-h i g (eintr) RET附带的Elisp介绍或其他介绍性的Lisp书籍,例如Touretzky (后者是针对Common Lisp的,但这是一个很好的介绍),而不是提供有关代码的提示。它将教你基础知识--例如,不仅仅是在函数定义中使用setq等等。
但为了给你一个例子,这里是copy-tree的定义(或者,只需在你的Emacs:M-x find-function RET copy-tree RET中查看它):
(defun copy-tree (tree &optional vecp)
"Make a copy of TREE.
If TREE is a cons cell, this recursively copies both its car and its cdr.
Contrast to `copy-sequence', which copies only along the cdrs. With second
argument VECP, this copies vectors as well as conses."
(if (consp tree)
(let (result)
(while (consp tree)
(let ((newcar (car tree)))
(if (or (consp (car tree)) (and vecp (vectorp (car tree))))
(setq newcar (copy-tree (car tree) vecp)))
(push newcar result))
(setq tree (cdr tree)))
(nconc (nreverse result) tree))
(if (and vecp (vectorp tree))
(let ((i (length (setq tree (copy-sequence tree)))))
(while (>= (setq i (1- i)) 0)
(aset tree i (copy-tree (aref tree i) vecp)))
tree)
tree)))发布于 2013-06-03 03:58:51
Elisp具有函数copy-tree。它是copy-sequence的递归版本
示例
(let* ((orig '((1 2) (3 4)))
(copy (copy-tree orig)))
(setcdr (cadr copy) '(0))
(list orig copy))
==> (((1 2) (3 4)) ((1 2) (3 0)))在你的例子中,你可以这样写:
(setq oList (copy-tree iList))https://stackoverflow.com/questions/16886220
复制相似问题