从循环宏进行递归调用

Making a recursive call from the loop macro

我对 common lisp 还很陌生,一直被某个特定问题所困扰。我想写的函数有两个参数:一个函数和一个列表。它遍历列表并对列表中的每个元素调用给定的函数。如果函数 returns 为真,则该元素将添加到返回的子列表中

到目前为止我尝试过的是:

(defun myFunc(f l)
  (loop for x in l
        if (listp x) do (myFunc f x)
        else if (eql t (funcall f x))
        collect x
        )
  )

我为 f 指定的函数接受一个参数,如果它是一个数字,returns 为真。到目前为止,如果 aList 是一个简单的列表,例如 (1 2 3),我的代码就可以工作。但是,当我输入像 (1 2 (4 5) 7) 这样的嵌套列表时,只会输出 (1 2 7) 而不是 (1 2 (4 5) 7).

我假设它与我的递归调用和返回的内容有关。非常感谢对此的一些帮助

有几个小问题。首先,我认为这只是一个错字,但您需要将 aFunc 替换为 f(因为您的代码中没有变量 aFunc)。

现在进入问题的重点。在您的 else if 分支中,您正确地 collect 谓词为真时的值。但是在递归的情况下,您只需 运行 一些代码并丢弃结果。你也会想要 collect 那里。

(defun myFunc (f l)
  (loop for x in l
        if (listp x)
          collect (myFunc f x)
        else if (eql t (funcall f x))
          collect x))

最后,只是一个样式注释。如果谓词 returns 为真,而不仅仅是 t,则通常将谓词视为真更为惯用。所以如果我正在写这篇文章,我可能会用简单的 (funcall f x) 替换 (eql t (funcall f x))。如果这是一项家庭作业,而老师告诉你用另一种方式做,那就坚持做。但如果为了您的利益,您也可以考虑更改它。