cdrを修正するもっとも低レベルの基本関数はsetcdr
です。
この関数は、consの新たなcdrとしてobjectを格納し、 以前のcdrを置き換える。 いいかえれば、consのcdrスロットがobjectを指すように変更する。 この関数は値objectを返す。
リストのcdrを別のリストで置き換える例を示します。 リストの最初の要素以外は取り除かれ、 要素の別のシーケンスになります。 最初の要素は変更されません。 というのは、それはリストのcarの中にあり、 cdrからは辿れないからです。
(setq x '(1 2 3)) ⇒ (1 2 3) (setcdr x '(4)) ⇒ (4) x ⇒ (1 4)
リスト内のコンスセル群のcdrを変更することで、
リストの中ほどの要素を削除できます。
つぎの例は、リスト(a b c)
の最初のコンスセルのcdrを変更することで、
このリストの第2要素b
を削除します。
(setq x1 '(a b c)) ⇒ (a b c) (setcdr x1 (cdr (cdr x1))) ⇒ (c) x1 ⇒ (a c)
箱表記では、この結果はつぎのようになります。
-------------------- | | -------------- | -------------- | -------------- | car | cdr | | | car | cdr | -->| car | cdr | | a | o----- | b | o-------->| c | nil | | | | | | | | | | -------------- -------------- --------------
以前に要素b
を保持していた2番目のコンスセルはまだ存在していて、
そのcarもまだb
ですが、このリストの一部ではありません。
cdrを変更して新たな要素を挿入するのも同様に簡単です。
(setq x1 '(a b c)) ⇒ (a b c) (setcdr x1 (cons 'd (cdr x1))) ⇒ (d b c) x1 ⇒ (a d b c)
箱表記では、この結果はつぎのようになります。
-------------- ------------- ------------- | car | cdr | | car | cdr | | car | cdr | | a | o | -->| b | o------->| c | nil | | | | | | | | | | | | --------- | -- | ------------- ------------- | | ----- -------- | | | --------------- | | | car | cdr | | -->| d | o------ | | | ---------------