首先,请注意,您在编写这样的代码时在技术上是正确的(最好的一种正确):
(let ((wireList ()))
(dolist (x (table-wires inputTable) wireList)
…)
这确实意味着dolist正在返回wireList。问题标题“从 dolist 循环返回列表,而不是返回 NIL”有点误导,因为:(i)nil 是一个列表,所以你返回一个列表;(ii) 你要回来了wireList。问题是您wireList在执行dolist. 该函数cons只是返回一个新的 cons 单元格;它不修改地方,所以你不修改wireList. 您可以改用push,就像下面的代码一样。由于您使用的是if无其他部分,因此您可以使用when.
(defun table-wires-position(inputTable inputPosition)
(let ((wireList ()))
(dolist (x (table-wires inputTable) wireList)
(when (or (equal-position-p (wire-OriginCoin x) inputPosition)
(equal-position-p (wire-destinCoin x) inputPosition))
(push x wireList))))) ; or (setf wireList (cons x wireList))
在风格节点上,我经常将&aux变量用于这些结果变量;它避免了嵌套级别:
(defun table-wires-position (inputTable inputPosition &aux (wireList '()))
(dolist (x (table-wires inputTable) wireList)
(when (or (equal-position-p (wire-OriginCoin x) inputPosition)
(equal-position-p (wire-destinCoin x) inputPosition))
(push x wireList))))
请注意,通过push将元素添加到列表中,您可以从inputTable. 如果您愿意,您可以通过返回以相同的顺序获得它们(nreverse wireList)。更好的是,由于您实际上只是返回删除了某些元素的列表,因此您不妨使用remove-if-not:
(defun table-wires-position (inputTable inputPosition)
(remove-if-not #'(lambda (x)
(or (equal-position-p (wire-OriginCoin x) inputPosition)
(equal-position-p (wire-destinCoin x) inputPosition)))
inputTable))