gpt4 book ai didi

Elisp深度复制-精简

转载 作者:行者123 更新时间:2023-12-04 09:36:04 26 4
gpt4 key购买 nike

我正在尝试在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) )))

然后,在 iList(1 2 3 4 5 6)的情况下,碰巧 oList是: (((((1 . 2) . 3) . 4) . 5) . 6)即嵌套列表。

我尝试使用附加语句引用,反引用,切换 oList(car iList)(cons # #)中的顺序,谷歌搜索解决方案,但是我没有运气(错误或垃圾)。

除了对已经存在的可以执行我想要的功能的任何受欢迎的评论之外,在代码中存在弱点的地方(我是一位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)
)

最佳答案

使用copy-tree(为方便起见,示例假定您为require d 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随附的Elisp简介,而不是提供有关代码的提示: C-h i g (eintr) RET或其他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)))

关于Elisp深度复制-精简,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16886220/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com