如何判断列表是否包含第三项?

时间:2009-03-19 22:20:07

标签: lisp scheme

我有一个函数,它接受一个包含两个或三个元素的列表。

;; expecting either ((a b c) d) or ((a b c) d e)
(define (has-third-item ls)
      (if (null? (caddr ls))
          false
          true)
      )

但是这段代码失败了

mcar: expects argument of type <mutable-pair>; given ()

(null?(caddr ls))表达式。

我也试过

(eq? '() (caddr ls))

但它也没有用。如何判断是否有第三项?

5 个答案:

答案 0 :(得分:9)

你不想要caddr,你想要(if(null?(cddr ls))...或者只是使用length来查找列表的长度,并将它与你感兴趣的值进行比较。< / p>

终止列表的'()将始终位于一对的cdr位置,因此在汽车位置(cad + r将执行)查找它不会有效。

答案 1 :(得分:4)

问题是,如果你有一个包含两个或更少项目的列表,你就不能拿它的caddr。试试这个:

(define (has-third-item lst)
  (<= 3 (length lst)))

在某些情况下,获取列表的长度可能效率低下(例如包含数百万项的列表);在这种情况下,我们可以测试列表是否长度为零,一或二:

(define (has-third-item lst)
  (not (or (null? lst)
           (null? (cdr lst))
           (null? (cddr lst)))))

编辑关于two other答案,在这种情况下,由于输入域由包含两个或三个元素的列表组成,因此cddr可能有效对于零或一的列表,第三项仍然会失败。为了普遍性,我建议使用适用于任何域的解决方案。

答案 2 :(得分:1)

如果您知道您的列表中有两个或三个元素(如您所说),则可以执行

(define (has-third-item? l)
  (not (null? (cddr l))))

您正在检查第二个cons小区(cddr l)是否有cdr。您不必检查l本身是否为null或l只有一个元素,除非您需要更通用的函数。

答案 3 :(得分:0)

尝试...

(and l (cdr l)(cddr l))

答案 4 :(得分:0)

为什么不使用(第三个ls)

如果没有,则返回第三个元素或NIL。