Next: List Variables, Previous: List Elements, Up: Lists [Contents][Index]
リストはLispの中核にあたる機能なので、リストを構築するために多くの関数があります。cons
はリストを構築する基本的な関数です。しかしEmacsのソースコードでは、cons
よりlist
のほうが多く使用されているのは興味深いことです。
この関数は新しいリスト構造を構築するための、もっとも基本的な関数である。この関数はobject1をCAR、object2をCDRとする新しいコンスセルを作成して、それから新しいコンスセルをリターンする。引数object1とobject2には任意のLispオブジェクトを指定できるが、ほとんどの場合object2はリストである。
(cons 1 '(2)) ⇒ (1 2)
(cons 1 '()) ⇒ (1)
(cons 1 2) ⇒ (1 . 2)
リストの先頭に1つの要素を追加するために、cons
がよく使用される。これをリストに要素をコンスすると言います。2たとえば:
(setq list (cons newelt list))
この例で使用されているlist
という名前の変数と、以下で説明するlist
という名前の関数は競合しないことに注意されたい。すべてのシンボルが、変数ト関数の両方の役割を果たすことができる。
この関数はobjectsを要素とするリストを作成する。結果となるリストは常にnil
終端される。objectsを指定しないと空リストがリターンされる。
(list 1 2 3 4 5) ⇒ (1 2 3 4 5)
(list 1 2 '(3 4 5) 'foo) ⇒ (1 2 (3 4 5) foo)
(list) ⇒ nil
この関数は各要素がobjectであるような、length個の要素からなるリストを作成する。make-list
とmake-string
(Creating Stringsを参照)を比較してみよ。
(make-list 3 'pigs) ⇒ (pigs pigs pigs)
(make-list 0 'pigs) ⇒ nil
(setq l (make-list 3 '(a b))) ⇒ ((a b) (a b) (a b)) (eq (car l) (cadr l)) ⇒ t
この関数はsequencesのすべての要素を含むリストをreturnします。sequencesにはリスト、ベクター、ブールベクター、文字列も指定できるが、通常は最後にリストを指定すること。最後の引数を除くすべての引数はコピーされるので、変更される引数はない(コピーを行なわずにリストを結合する方法についてはRearrangementのnconc
を参照のこと)。
より一般的にはappend
にたいする最後の引数は、任意のLispオブジェクトを指定できる。最後の引数はコピーや変換はされない。最後の引数は、新しいリストの最後のコンスセルのCDRとなる。最後の引数もリストならば、このリストの要素は実質的には結果リストの要素になる。最後の要素がリストでなければ、最後のCDRが(真リストで要求される)nil
ではないので、結果はドットリストになる。
以下はappend
を使用した例です:
(setq trees '(pine oak)) ⇒ (pine oak) (setq more-trees (append '(maple birch) trees)) ⇒ (maple birch pine oak)
trees ⇒ (pine oak) more-trees ⇒ (maple birch pine oak)
(eq trees (cdr (cdr more-trees))) ⇒ t
append
がどのように機能するか、ボックスダイアグラムで確認できます。変数trees
はリスト(pine
oak)
にセットされ、それから変数more-trees
にリスト(maple birch pine
oak)
がセットされます。しかし変数trees
は継続して元のリストを参照します:
more-trees trees | | | --- --- --- --- -> --- --- --- --- --> | | |--> | | |--> | | |--> | | |--> nil --- --- --- --- --- --- --- --- | | | | | | | | --> maple -->birch --> pine --> oak
空のシーケンスはappend
によりリターンされる値に寄与しません。この結果、最後の引数にnil
を指定すると、それより前の引数のコピーを強制することになります。
trees ⇒ (pine oak)
(setq wood (append trees nil)) ⇒ (pine oak)
wood ⇒ (pine oak)
(eq wood trees) ⇒ nil
関数copy-sequence
が導入される以前は,これがリストをコピーする通常の方法でした。Sequences Arrays Vectorsを参照してください。
以下はappend
の引数としてベクターと文字列を使用する例です:
(append [a b] "cd" nil) ⇒ (a b 99 100)
apply
(Calling Functionsを参照)の助けを借りることにより、リストのリストの中のすべてのリストをappendできます。
(apply 'append '((a b c) nil (x y z) nil)) ⇒ (a b c x y z)
sequencesが与えられなければnil
がリターンされます:
(append) ⇒ nil
以下は最後の引数がリストでない場合の例です:
(append '(x y) 'z) ⇒ (x y . z) (append '(x y) [z]) ⇒ (x y . [z])
2番目の例は最後の引数はリストではないシーケンスの場合で、このシーケンスの要素は、結果リストの要素にはなりません。かわりに最後の引数がリストでないときと同様、シーケンスが最後のCDRになります。
この関数はツリーtree
のコピーをリターンする。treeがコンスセルなら、同じCARとCDRをもつ新しいコンスセルを作成してから、同じ方法によりCARとCDRを再帰的にコピーする。
treeがコンスセル以外の場合、通常はcopy-tree
は単にtreeをリターンする。しかしvecpが非nil
なら、この関数はベクターでもコピーします(そしてベクターの要素を再帰的に処理する)。
これはfromからseparationづつインクリメントして、toの直前で終わる、数字のリストをリターンする。separationには正か負の数を指定でき、デフォルトは1。toがnil
、または数値的にfromと等しければ、値は1要素のリスト(from)
になる。separationが正でtoがfromより小さい、またはseparationが負でtoがfromより大きければ、これらの引数は空のシーケンスを指示することになるので、値はnil
になります。
separationが0で、toがnil
でもなく、数値的にfromとも等しくまければ、これらの引数は無限シーケンスを指示することになるので、エラーがシグナルされる。
引数はすべて数字である。浮動少数点数の計算は正確ではないので、浮動少数点数の引数には注意する必要がある。たとえばマシンへの依存により、(number-sequence
0.4 0.8 0.2)
が3要素のリストをリターンして、(number-sequence 0.4 0.6
0.2)
が1要素のリスト(0.4)
をリターンnすることがよく起こる。リストのn番目の要素は、厳密に(+
from (* n
separation))
という式により計算される。リストに確実にtoが含まれるようにするために、この式に適切な型のtoを渡すことができる。別の方法としてtoを少しだけ大きな値(separationが負なら少しだけ小さな値)に置き換えることもできる。
例をいくつか示す:
(number-sequence 4 9) ⇒ (4 5 6 7 8 9) (number-sequence 9 4 -1) ⇒ (9 8 7 6 5 4) (number-sequence 9 4 -2) ⇒ (9 7 5) (number-sequence 8) ⇒ (8) (number-sequence 8 5) ⇒ nil (number-sequence 5 8 -1) ⇒ nil (number-sequence 1.5 6 2) ⇒ (1.5 3.5 5.5)
リストの最後に要素を追加するための、これと完全に同等な方法はありません。listnameをコピーすることにより新しいリストを作成してから、neweltをそのリストの最後に追加する(append
listname (list
newelt))
を使用することができます。すべてのCDRを辿って終端のnil
を置き換える、(nconc
listname (list
newelt))
を使用することもできます。コピーも変更も行なわずにリストの先頭に要素を追加するcons
と比較してみてください。
Next: List Variables, Previous: List Elements, Up: Lists [Contents][Index]