【问题标题】:Making a recursive call from the loop macro从循环宏进行递归调用
【发布时间】:2021-02-08 08:59:12
【问题描述】:

我对 common lisp 还是很陌生,并且一直被困在一个特定的问题上。我想写的函数有两个参数:一个函数和一个列表。它遍历列表并在列表中的每个元素上调用给定的函数。如果函数返回 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 是一个简单的列表,例如 (1 2 3),我的代码就可以工作。但是,当我输入像 (1 2 (4 5) 7) 这样的嵌套列表时,只会输出 (1 2 7) 而不是 (1 2 (4 5) 7)。

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

【问题讨论】:

    标签: loops recursion lisp common-lisp


    【解决方案1】:

    有几个小问题。首先,我认为这只是一个错字,但您需要将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))
    

    最后,只是一个风格说明。如果谓词返回任何真实的东西,而不仅仅是t,则将谓词视为真实通常更为惯用。所以如果我在写这篇文章,我可能会用简单的(funcall f x) 替换(eql t (funcall f x))。如果这是一项家庭作业,而老师告诉你用另一种方式来做,那就坚持下去。但如果是为了你的利益,你也可以考虑改变它。

    【讨论】:

      猜你喜欢
      • 2018-09-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-11
      • 1970-01-01
      相关资源
      最近更新 更多