ド素人が始めるCommon Lisp 9. リスト再び

Common Lisp ド素人

以前リストについて書きましたがあれは本当にさわりの部分だったようだ。まだまだたくさんリストに関して学ぶことがある。さすがLISP!

今回はリストをデータとして扱っていくうえで有用なその他たくさんの関数等を見ていく。

Contents

この記事に出てくる関数一覧

function description
append 複数のリストを連結して新たなリストを作る。
reverse リストの要素を逆順とした新たなリストを作る。
nth n番目の要素を取得する。nは0から数える。
nthcdr n番目の要素から残りの要素を持つ新たなリストを作る。nは0から数える。
last 最後の要素のみを要素とする新たなリストを作る。
remove リストの要素から特定の要素を取り除いたリストを作る。

リスト操作

first, rest, car, cdr,cons, list 復習

既に習得したことになっている関数の復習をしておこう。
first: リストの最初の要素を返す。

(first '(a b c d))  ; => A

rest: 2番目以降の要素を持ったリストを返す。正確にはコンスセルのcdr部分なのでリストとは限らない。コンスセルの残り半分はcdr以外に表現方法はあるのか?

(rest '(a b c d))   ; => (B C D)

car: firstと同じ
cdr: restと同じ
cons: 二つの引数を受けてれらをfirstrestとするコンスセルを作る。

(cons 'a '(b c d))  ; => (A B C D)
(cons 'a 'b)    ; => (A.B)

list: 引数でリストを作る

(list 'a 'b 'c 'd)  ; => (A B C D)

ここまでは前回もやった内容。

append: リストを連結する

appendを使うとリスト同士を連結した新たなリストを得る。引数はリストでなければならない。

(append '(c o m m o n) '(l i s p))  ; => (C O M M O N L I S P)

引数は3つ以上でもよい

(append '(a b) '(c d) '(e f))   ; =>(A B C D E F)

reverse: リストを反転する

reverseを使うと要素の順番を反転させたリストを得る。引数はリストに限らずsequenceであればいいらしい。sequenceについてはまだ詳細はわからないがリストよりも大きい概念と思われる。配列とかも含まれるんじゃなかろうか。とりあえず文字列は反転された。

(reverse '(a b c d))    ; => (D C B A)
(reverse "abcd")    ; => "dcba"

nth, nthcdr: first、car、cdrの一般化

nthを使うとn番目の要素を得る。このときnは0から数える。つまり、(nth 0 'any-list)(first 'any-list)と同じだし、(nth 1 'any-list)(second 'any-list)と同じということだ。ややこしいがしょうがない。
nthcdrを使うとn番目の要素から残りの要素を持つリストを得る。このときnは0から数える。つまり(nthcdr 0 'any-list)は元のリストany-listと等しい。cdrをn回適用したと考えておけばいいだろう。
nilcarcdrnilなのでnが要素数よりも多い場合はnilが返る。

(nth 0 '(a b c d))  ; => A
(nth 1 '(a b c d))  ; => B
(nth 2 '(a b c d))  ; => C
(nth 3 '(a b c d))  ; => D
(nth 4 '(a b c d))  ; => NIL
(nthcdr 0 '(a b c d))   ; => (A B C D)
(nthcdr 1 '(a b c d))   ; => (B C D)
(nthcdr 2 '(a b c d))   ; => (C D)
(nthcdr 3 '(a b c d))   ; => (D)
(nthcdr 4 '(a b c d))   ; => NIL

上記を見てもわかる通り、nth 0carと同じだがnthcdr 0cdrではない。nthcdr 1cdrと同じ。

last: リストの最後の要素のみを要素とするリストを作る

lastを使うと引数のリストの最後の要素をリストとして得る。

(last '(a b c d))   ; => (D)

リストと書いたがコンスセルを得るが正しいのかもしれない。
例えば

(last '(a b c . d)) ; => (C . D)

のようにドットリストの場合は最後のコンスセルが返ってくる。

remove: リストの要素を削除する

removeを使うと指定した要素を削除したリストを得る。重複している場合はすべて削除される。一部のみ削除する方法も別にあるらしい。

(remove 'c '(c o m m o n))  ; => (O M M O N)
(remove 'o '(c o m m o n))  ; => (C M M N)

次回へ続く

長くなったのでこの記事はここまでにしておく。引き続き以下を学んでいきます。

  • 集合としてリストを使う
  • テーブルとしてリストを使う

コメント

タイトルとURLをコピーしました