Next: , Previous: Setcar, Up: Modifying Lists


5.6.2 リストのCDRの変更

cdrを修正するもっとも低レベルの基本関数はsetcdrです。

— Function: setcdr cons object

この関数は、consの新たなcdrとしてobjectを格納し、 以前のcdrを置き換える。 いいかえれば、conscdrスロットが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------
             |       |       |
              ---------------