コンテンツにスキップ

Lisp/基本/List

出典: フリー教科書『ウィキブックス(Wikibooks)』
この項目は 未完成 です。加筆、改善を歓迎します。

Common Lisp の list は cons セル と呼ばれるもののペアから成り立っています。それぞれのセルは二つの部品を持っていて、それぞれの名前は歴史的経緯で car(セルの最初の部分)とcdr(セルの残りの部分)と言います。

(car . cdr)

List は最初のセルの cdr が、別の consセル へのポインタを保持した cons セル によって実装されています。

空の list は nil としても理解され、そのまま nil という表現で表記されるか、空の list () という表現で表記されます。

cons 関数を使用すれば右部分と左部分がある新しい consセル から成る list を作ることが出来ます。

  (cons 'a '())                      (A)
  (cons 'a '(b))                     (A B)
  (cons 'a (cons 'b (cons 'c nil)))  (A B C)

list ではない consセル を作成することも可能だと憶えておいてください。

  (cons 'a 'b)  (A . B)

これはドットリストと呼ばれます。適正な list にするには連なった consセル の最後の cdr が空の list(nil) にポインタを保持していなければなりません。 list 関数を使用して list を作ることも出来ます。

  (list 'a 'b 'c)    (A B C)

上の式は下の表現と同様です。

  (cons 'a (cons 'b (cons 'c '())))  (A B C)
  (cons 'a (cons 'b (cons 'c nil)))  (A B C)
  (cons 'a '(b c))                   (A B C)
  '(a b c)                           (A B C)

List のそれぞれの要素を取得するには car 関数(あるいは first 関数)、 cdr 関数(あるいは rest 関数)を使用します。

  (setf list '(a b c))
  (car list)     a
  (first list)   a

  (cdr list)     (b c)
  (rest list)    (b c)

Common Lisp においては second 関数、 third 関数、 forth 関数(以上 tenth まで続く)が定義されています。 second 関数は cdrrest とは違うということに注意してください。 cdrrest は list の最初の要素の後の残りの list を返します。一方で second は list の2番目の要素を返します。

  (rest list)    (b c)
  (second list)  b
  (third list)   c
  (fourth list)  nil

List は連なった順序になっているので、順序を操作する関数は list も操作します。

  (subseq list 0 1)   (a)
  (subseq list 0 2)   (a b)

nth 関数は list から選択した項目を抜き出します。

  (nth 0 list)   a

最初の項目は 0th だということに注意してください。 Common Lisp はいくつもの list を操作するフォーム(関数やマクロのことです)を持っています。 mapcar は list のそれぞれの要素を、一度に一つずつ新しい list を作り出す処理に使うことができます。

  (defun add2 (n)
    (+ 2 n))
  (mapcar #'add2 '(1 2 3))   (3 4 5)

上の例では、一つの list に対して mapping しています。そのため単項関数(引数を一つとる関数)を使いました。 #' は引数として関数を渡すための特殊な方法です。このことに関しては次の章で詳しく紹介します。一つ以上の list を map することも可能です。関数は list にある同じ数の引数をとらなくてはなりません。

  (mapcar #'+ '(1 2 3) '(4 5 6))  (5 7 9)