我有一个函数,它接受一个包含两个或三个元素的列表。
;; 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))
但它也没有用。如何判断是否有第三项?
答案 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。