我对普通lisp还很陌生,我一直在处理一个特定的问题。我要编写的函数包含两个参数:一个函数和一个List。它遍历列表,并对列表中的每个元素调用给定的函数。如果函数返回true,则元素被添加到返回的子列表中
到目前为止,我尝试过的是:
(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的函数取一个参数,如果它是一个数字,则返回true。到目前为止,如果aList是一个简单的列表,比如(123(,我的代码就可以工作。然而,当我输入像(12(4 5(7(这样的嵌套列表时,只输出(1 2 7(而不是(1 2(4 5 7(。
我假设这与我的递归调用以及返回的内容有关。非常感谢在这个上提供一些帮助
有几个小问题。首先,我认为这只是一个拼写错误,但您需要将aFunc
替换为f
(因为您的代码中没有变量aFunc
(。
现在来谈谈问题的要点。在else if
分支中,当谓词为true时,可以正确地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))
最后,只是一个风格注释。如果谓词返回任何truthy,而不仅仅是t
,那么将其视为true通常更为惯用。因此,如果我在写这篇文章,我可能会用简单的(funcall f x)
替换(eql t (funcall f x))
。如果这是一项家庭作业,而老师让你用另一种方式做,那就坚持做下去。但如果这是为了你的利益,你也可以考虑改变这一点。