7.3 nthcdr

函数 nthcdr 与函数 cdr 相关联。它的作用是重复地取一个列表的 CDR

如果对列表 (pine fir oak maple) 进行 CDR 操作,将得到列表 (fir oak maple)。如果在这个结果上再进行一次 CDR,将得到列表 (oak maple)。当然,对原始列表反复 CDR 只会得到原始的 CDR,因为该函数不会改变列表。需要对 CDR 进行评估,然后继续操作。最终,你将得到一个空列表,在这个例子中,它显示为 nil 而非 ()

为了复习,以下是一系列重复的 CDR 操作,‘’ 后的文本显示了返回的结果。

(cdr '(pine fir oak maple))
     ⇒ (fir oak maple)

(cdr '(fir oak maple))
     ⇒ (oak maple)

(cdr '(oak maple))
     ⇒ (maple)

(cdr '(maple))
     ⇒ nil

(cdr 'nil)
     ⇒ nil

(cdr ())
     ⇒ nil

你也可以进行多次 CDR 操作而不打印中间值,像这样:

(cdr (cdr '(pine fir oak maple)))
     ⇒ (oak maple)

在这个例子中,Lisp 解释器首先评估最内层的列表。最内层的列表被引用,因此它只是将列表传递给最内层的 cdr。这个 cdr 将由列表的第二个及之后的元素组成的列表传递给最外层的 cdr,产生一个由原始列表的第三个及之后的元素组成的列表。在这个例子中,重复调用 cdr 函数并返回一个由原始列表的前两个元素之外的元素组成的列表。

函数 nthcdr 的作用与重复调用 cdr 相同。在下面的例子中,参数 2 被传递给函数 nthcdr,连同列表一起传递,返回的值是没有前两个项的列表,这与在列表上连续调用两次 cdr 是一样的:

(nthcdr 2 '(pine fir oak maple))
     ⇒ (oak maple)

使用原始的四个元素列表,我们可以看到当传递不同的数值参数给 nthcdr 时会发生什么,包括 0、1 和 5:

;; 保留列表不变。
(nthcdr 0 '(pine fir oak maple))
     ⇒ (pine fir oak maple)

;; 返回去掉第一个元素的列表副本。
(nthcdr 1 '(pine fir oak maple))
     ⇒ (fir oak maple)

;; 返回去掉三个元素的列表副本。
(nthcdr 3 '(pine fir oak maple))
     ⇒ (maple)

;; 返回去掉所有四个元素的列表副本。
(nthcdr 4 '(pine fir oak maple))
     ⇒ nil

;; 返回去掉所有元素的列表副本。
(nthcdr 5 '(pine fir oak maple))
     ⇒ nil