Next: , Previous: , Up: Modifying Lists   [Contents][Index]


5.6.2 リストのCDRの変更

CDRを変更するもっとも低レベルのプリミティブ関数はsetcdrです:

Function: setcdr cons object

この関数は前のCDRを置き換えて、consの新しいCDRobjectを格納する。言い換えると、この関数はconsCDRobjectを参照するように変更する。この関数は値objectをリターンする。

以下はリストのCDRを、他のリストに置き換える例です。1番目の要素以外のすべての要素は、別のシーケンスまたは要素のために取り除かれます。1番目の要素はリストのCARなので変更されず、CDRを通じて到達することもできないからです。

(setq x (list 1 2 3))
     ⇒ (1 2 3)
(setcdr x '(4))
     ⇒ (4)
x
     ⇒ (1 4)

リスト内のコンスセルのCDRを変更することにより、リストの途中から要素を削除できます。たとえば以下では、1番目のコンスセルのCDRを変更することにより、2番目の要素bをリスト(a b c)から削除します。

(setq x1 (list '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番目のコンスセルは依然として存在し、そのCARbのままですが、すでにこのリストの一部を形成していません。

CDRを変更して新しい要素を挿入するのも同じくらい簡単です:

(setq x1 (list '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------
        |       |       |
         ---------------