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

Kai*_*Kai 5 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)
      )
Run Code Online (Sandbox Code Playgroud)

但是这段代码失败了

mcar: expects argument of type <mutable-pair>; given ()
Run Code Online (Sandbox Code Playgroud)

在(null?(caddr ls))表达式上.

我也试过了

(eq? '() (caddr ls))
Run Code Online (Sandbox Code Playgroud)

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

Jay*_*nek 9

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

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


Kyl*_*nin 5

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

(define (has-third-item lst)
  (<= 3 (length lst)))
Run Code Online (Sandbox Code Playgroud)

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

(define (has-third-item lst)
  (not (or (null? lst)
           (null? (cdr lst))
           (null? (cddr lst)))))
Run Code Online (Sandbox Code Playgroud)

编辑:关于其他两个 答案,虽然在这种情况下使用 cddr 可能会起作用,因为输入域由具有两个或三个元素的列表组成,对于具有零或一的列表, has-third-item 仍然会失败。为了一般性,我建议使用适用于任何领域的解决方案。