gpt4 book ai didi

引用 cons 单元格

转载 作者:太空宇宙 更新时间:2023-11-03 18:45:50 28 4
gpt4 key购买 nike

如何设置变量指向列表单元格?

我正在尝试编写一个宏来将列表中的所有值乘以一个值。这是我目前拥有的:

(defmacro scale (areas scale)
`(dotimes (n (list-length ,areas))
(setf (nth n ,areas) (* (nth n ,areas) ,scale))))

我担心这不是最有效的做事方式,因为我两次查找第 n 个单元格。我宁愿设置一个变量指向第 n 个单元格,这样 setf 可以修改该单元格的值,并且 * 可以在它的计算中使用该单元格的值。

更好的方法是使用 dolist 并将变量设置为单元格引用。这有可能吗?

虽然我在这里,但当您有一个单元格时,是否也可以获取列表中的下一个单元格。有点像迭代器,这样我就可以做类似的事情:

(let ((area (car areas))
(loop while area do
(setf area (* area scale))
(setf area (next area))))

但我不知道如何区分设置指针或设置引用单元格的值。

我希望我说得有道理:)

最佳答案

第一个代码示例的主要问题不是它找到了 nth 单元格两次,但它确实使用了 nth。而不是获取 nth单元格,获取 下一个 单元格,它是前一个单元格的 cdr

你不需要宏,所以让我们实现一个函数。那里有多种方法可以对列表的每个 cons 单元格执行操作:

(defun scale (areas scale)
(do ((tail areas (cdr tail)))
((endp tail))
(setf (car tail)
(* (car tail) scale))))

(defun scale (areas scale)
(loop for tail on areas
do (setf (car tail)
(* (car tail) scale))))

(defun scale (areas scale)
(mapl (lambda (cell)
(setf (car cell)
(* (car cell) scale)))
areas))

有一个替代方案不涉及对 car 的显式操作每个单元格:

(defun scale (areas scale)
(map-into areas
(lambda (area)
(* area scale))
areas))

作为奖励,这里有一个类似于 dolist 的宏,用于修改主体中的“变量”传播到列表中:

(defmacro dolistref ((var list &optional result) &body body)
(let ((tail (gensym "TAIL"))
(head (gensym "HEAD")))
`(let ((,head ,list))
(symbol-macrolet ((,var (car ,tail)))
(do ((,tail ,head (cdr ,tail)))
((endp ,tail) ,result)
,@body)))))

;; usage example
(let ((a (list 1 2 3)))
(dolistref (item a a)
(incf item))) ;; => (2 3 4)

关于引用 cons 单元格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14987949/

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