1

你能帮我写代码吗,我不明白为什么它没有返回我的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)))))
4

3 回答 3

7

首先,请注意,您在编写这样的代码时在技术上是正确的(最好的一种正确):

(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))
于 2013-11-07T15:29:45.820 回答
1

小补充:

如果一个宏以dolike in开头dolist,它只是迭代并针对副作用进行迭代。因此,如果需要,将迭代结果放在某个地方是用户的任务。

如果它以collect或允许collect主体中的某个子句开头,那么它应该返回一个迭代结果列表。宏就是这样一种构造loop,但人们可能会在图书馆或书籍中找到其他迭代构造。

于 2013-11-07T16:59:25.007 回答
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))

也不要使用驼峰命名,因为符号不区分大小写,所以以下都是相同的

inputPosition INputPosition INPUTPOSITION iNpUtPoSiTiOn

始终使用连字符,例如输入位置

于 2013-11-07T16:03:19.897 回答