你能帮我解决一下我的代码,我不明白为什么它没有返回我的wireList,它只是返回NIL
(defun table-wires-position(inputTable inputPosition)
(let ((wireList () ))
(dolist (x (table-wires inputTable) wireList)
(if (or (equal-position-p (wire-OriginCoin x) inputPosition)
(equal-position-p (wire-destinCoin x) inputPosition))
(cons x wireList)))))
答案 0 :(得分:7)
首先,请注意您在编写代码时技术上是正确的(the best kind of correct):
(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
variables来表示这些结果变量;它避免了嵌套程度:
(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))
答案 1 :(得分:1)
约书亚的回答是这里的方法,但作为附录,这是使用循环宏的版本。
(defun table-wires-position (input-table input-position)
(loop :for x :in input-table
:if (or (equal-position-p (wire-origin-coin x) input-position)
(equal-position-p (wire-destin-coin x) input-position))
:collect x))
也不要使用camelcase名称,因为符号不区分大小写,因此以下所有相同
inputPosition INputPosition INPUTPOSITION iNpUtPoSiTiOn
总是使用例如输入位
答案 2 :(得分:1)
小补充:
如果宏在do
中以dolist
开头,则只需迭代并对副作用进行迭代。因此,如果需要,将迭代结果放在某处是用户任务。
如果它以collect
开头或者在正文的某处允许collect
子句,那么它应该返回一个迭代结果列表。 loop
宏是一个这样的构造,但是可以在库或书籍中找到其他迭代构造。