Next: 既存のリスト構造の変更, Previous: コンスセルおよびリストの構築, Up: リスト [Contents][Index]
以下の関数と1つのマクロは、変数に格納されたリストを変更する便利な方法を提供します。
このマクロはCARがelementで、CDRがlistnameのリストであるような新しいリストを作成して、そのリストをlistnameに保存する。listnameがリストに名前をつけるクォートされていないシンボルのときは単純で、この場合マクロは(setq listname (cons element listname))
と等価になる。
(setq l '(a b)) ⇒ (a b) (push 'c l) ⇒ (c a b) l ⇒ (c a b)
より一般的なのはlistname
が汎変数の場合である。この場合、このマクロは(setf listname (cons element listname))
と等価になる。ジェネリック変数を参照のこと。
リストから1番目の要素を取り出すpop
マクロについては、リスト要素へのアクセスを参照されたい。
以下の2つの関数は、変数の値であるリストを変更します。
この関数はelementがsymbolの値のメンバーでなければ、symbolにelementをコンスすることにより、変数symbolをセットする。この関数はリストが更新されているか否かに関わらず、結果のリストをリターンする。symbolの値は呼び出し前にすでにリストであることが望ましい。elementがリストの既存メンバーか比較するために、add-to-list
はcompare-fnを使用する。compare-fnがnil
ならequal
を使用する。
elementが追加される場合は、通常はsymbolの前に追加されるが、オプションの引数appendが非nil
なら最後に追加される。
引数symbolは暗黙にクォートされない。setq
とは異なりadd-to-list
はset
のような通常の関数である。クォートしたい場合には自分で引数をクォートすること。
symbolがレキシカル変数を参照する際にはこの関数を使用しないこと。
以下にadd-to-list
を使用する方法をシナリオで示します:
(setq foo '(a b)) ⇒ (a b) (add-to-list 'foo 'c) ;;c
を追加 ⇒ (c a b) (add-to-list 'foo 'b) ;; 効果なし ⇒ (c a b) foo ;;foo
が変更された ⇒ (c a b)
以下は(add-to-list 'var value)
と等価な式です:
(if (member value var) var (setq var (cons value var)))
この関数は古い値のorder
(リストであること)で指定された位置に、elementを挿入して変数symbolをセットする。elementがすでにこのリストのメンバなら、リスト内の要素の位置はorderにしたがって調整される。メンバーか否かはeq
を使用してテストされる。この関数は更新されているかどうかに関わらず、結果のリストをリターンする。
orderは通常は数字(整数か浮動小数点数)で、リストの要素はその数字の昇順で並べられる。
orderは省略またはnil
を指定できる。これによりリストにelementがすでに存在するなら、elementの数字順序は変更されない。それ以外ならelementは数字順序をもたない。リストの数字順序をもたない要素はリストの最後に配置され、特別な順序はつかない。
orderに他の値を指定すると、elementがすでに数字順序をもつときは数字順序が削除される。それ以外はならnil
と同じ。
引数symbolは暗黙にクォートされない。add-to-ordered-list
はsetq
などとは異なり、set
のような通常の関数である。必要なら引数を自分でクォートすること。
順序の情報はsymbolのlist-order
プロパティーにハッシュテーブルで保存される。symbolはレキシカル変数を参照できない。
以下にadd-to-ordered-list
を使用する方法をシナリオで示します:
(setq foo '()) ⇒ nil (add-to-ordered-list 'foo 'a 1) ;;a
を追加 ⇒ (a) (add-to-ordered-list 'foo 'c 3) ;;c
を追加 ⇒ (a c) (add-to-ordered-list 'foo 'b 2) ;;b
を追加 ⇒ (a b c) (add-to-ordered-list 'foo 'b 4) ;;b
を移動 ⇒ (a c b) (add-to-ordered-list 'foo 'd) ;;d
を後に追加 ⇒ (a c b d) (add-to-ordered-list 'foo 'e) ;;e
を追加 ⇒ (a c b e d) foo ;;foo
が変更された ⇒ (a c b e d)