我试图使用标准的循环工具来收集结果,但它只返回nil。为什么会这样呢?我觉得这应该行得通:
(defun coll-intersects (bounds mv)
(let ((res (list))
(loop for x from (first bounds) to (+ (first bounds) (third bounds)) do
(loop for y from (second bounds) to (+ (second bounds) (fourth bounds))
if (not (member (cl-byte (aref mapa x y)) mv))
collect (aref mapa x y) into res
))))但不,我必须这么做:
(defun coll-intersects (bounds mv)
(let ((res (list)))
(loop for x from (first bounds) to (+ (first bounds) (third bounds)) do
(loop for y from (second bounds) to (+ (second bounds) (fourth bounds))
do
(if (not (member (cl-byte (aref mapa x y)) mv))
(push (aref mapa x y) res))
))
res))为什么?我真的很困惑为什么第一个不能工作
发布于 2021-06-03 19:48:33
正如Ehvince的回答所说,问题是
(loop ...
collect ... into x
...)绑定x。此构造的目的实际上是让您可以收集多个列表:
(defun partition (l)
(loop for e in l
if (evenp e)
collect e into evens
else
collect e into odds
finally (return (values evens odds))))例如。
如果你想从嵌套循环中收集一个列表,并且你关心的是顺序,你可以这样做:
(defun sublist-evens (l)
(loop for s in l
nconcing
(loop for e in s
when (evenp e)
collect e)))在这里,外部循环本质上是将来自内部循环的结果nconc在一起。这当然可以嵌套:
(loop ...
nconcing
(loop ...
nconcing
(loop ...
collect ...)))都会起作用的。也有可能loop足够聪明,可以保持一个指向它使用nconc / nconcing构建的列表的尾部指针,尽管您必须检查这一点。
但是,如果您想从一些深度嵌套的循环(或任何其他搜索过程)按顺序构建一些列表,我发现使用collecting macro来做这件事几乎总是更令人愉快的(免责声明:这篇文章是我写的)。使用这样的宏,上面的sublist-evens函数如下所示:
(defun sublist-evens (l)
(collecting
(dolist (s l)
(dolist (e s)
(when (evenp e) (collect e))))))和
> (sublist-evens '((1 2 3) (4 5 6)))
(2 4 6)你可以做得更好:
(defun tree-partition (tree)
(with-collectors (evens odds)
(labels ((search (it)
(typecase it
(list
(dolist (e it)
(search e)))
(integer
(if (evenp it)
(evens it)
(odds it)))
(t
(warn "unexpected ~A" (type-of it))))))
(search tree))))而现在
> (tree-partition '(((1 2 3) (4)) 5))
(2 4)
(1 3 5)(对于hack值,您可以使用another macro来更简洁地表达上面的内容:
(defun tree-partition (tree)
(with-collectors (evens odds)
(iterate search ((it tree))
(typecase it
(list
(dolist (e it)
(search e)))
(integer
(if (evenp it)
(evens it)
(odds it)))
(t
(warn "unexpected ~A" (type-of it)))))))免责声明:那个宏也是我写的。)
https://stackoverflow.com/questions/67817363
复制相似问题