在 Common Lisp 中使用 if 条件将项目添加到列表中

问题描述 投票:0回答:1

我是 lisp 新手,我正在尝试解决一些基本练习。我正在尝试在输入列表中创建超出最大和最小限制的元素列表。我一直在尝试通过创建两个函数来做到这一点。第一个是设置限制,第二个是为列表中的每个元素运行第一个函数,但我的代码只打印输入列表。

(defun limits (x)
  (setq out nil)
  (if (> x 2)
      (push (list x) out)
      (if (< x 5)
          (push (list x) out)
          ())))

(defun out-of-limits (l)
  mapcar #'limits l)
list common-lisp
1个回答
0
投票

正如注释中所解释的,要进行函数调用,必须将其括在括号中:

> (defun out-of-limits (l)
     (mapcar #'limits  l) )
  ;  ^                  ^       here

现在打电话

(out-of-limits (list 1 2 3))
和打电话一样

(list (limits 1) (limits 2) (limits 3))

这意味着我们不需要尝试手动将结果推入任何变量,例如

out
。无论如何,它们都会被收集到退货列表中。

因此我们只需要写

(defun limits (x)
  (if (> x 2)
      (list x)
      (if (< x 5)
          (list x)
          ())))

但这与

相同
(defun limits (x)
  (if (or (> x 2) (< x 5))
      (list x)
      ()))

我们现在就来尝试一下吧

> (out-of-limits (list 1 4 10))
((1) (4) (10))

确实

or
测试是错误的。现在你明白为什么了吗?

没错。 任何数都可以满足它。我们需要将其更改为

(defun limits (x)
  (if (or (< x 2) (> x 5))
      (list x)
      ()))

现在我们有了

> (out-of-limits (list 1 4 10))
((1) () (10))

剩下的就是将所有这些内部列表附加到一起。这是通过使用

#'mapcan
代替
#'mapcar
来实现的:

(defun out-of-limits (l)
     (mapcan #'limits  l))

现在所有内部括号都会消失。测试,我们得到

> (out-of-limits (list 1 4 10))
(1 10)
© www.soinside.com 2019 - 2024. All rights reserved.