GNU Emacs 32.0.50 (9008bf64c3) のマニュアルを PLaMo 翻訳で機械翻訳したものです。誤訳を含むことがあります。原文: https://www.gnu.org/software/emacs/manual/html_node/elisp/Setcdr.html ・ emacs-doc.conao3.com

5.6.2 ListのCDRを変更する

CDR を変更するための最も低レベルなプリミティブは setcdr です:

関数: setcdr cons object

この関数は、cons の新しい CDR として object を格納し、それまでの CDR を置き換えます。言い換えれば、cons の CDR スロットを object を指すように変更します。そして、値 object を返します。

以下に、リストのCDRを別のリストに置き換える例を示します。リストの最初の要素を除くすべての要素が削除され、代わりに別の要素列が配置されます。最初の要素はリストのCARに格納されており、CDR経由では到達できないため、変更されません。

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

リスト内のコンスセルのCDRを変更することで、リストの途中にある要素を削除できます。例えば、ここでは最初のコンスセルのCDRを変更することで、リスト(a b c)から2番目の要素bを削除します:

(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番目の cons セルは依然として存在し、その CAR も依然として b であるが、もはやこのリストの一部を構成していない。

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------
        |       |       |
         ---------------