Next: Association Lists, Previous: Modifying Lists, Up: Lists [Contents][Index]
リストは順序なしの数学的集合 — リスト内に要素があれば集合の要素の値とされ、リスト内の順序は無視される —
を表すことができます。2つの集合を結合(union)するには、(重複する要素を気にしない場合は)appendを使用します。equalである重複を取り除くには、delete-dupsを使用します。集合にたいする他の有用な関数には、memqやdelq、およびこれらのequalバージョンであるmemberとdeleteが含まれます。
Common Lispに関する注意: 集合を処理するために、Common Lispには(要素の重複がない)関数
unionがあります。これらの関数は標準のGNU Emacs Lispにはありませんが、cl-libはこれらを提供します。Lists as Sets in Common Lisp Extensionsを参照してください。
この関数は、objectがlistのメンバーかどうかをテストします。メンバーの場合、memqはobjectで最初に見つかった要素から開始されるリストをreturnします。メンバーでない場合は、nilをreturnします。memqの文字‘q’は、この関数がobjectとリスト内の要素の比較に、eqを使用することを示します。たとえば:
(memq 'b '(a b c b a))
⇒ (b c b a)
(memq '(2) '((1) (2))) ; (2)と(2)はeqではない。
⇒ nil
この関数listからはobjectとeqなすべての要素を破壊的に取り除いて、結果のリストをreturnします。delqの文字‘q’は、この関数がobjectとリスト内の要素の比較に、eqを使用することを示します(memqやremqと同様)。
delqを呼び出すときは通常、元のリストを保持していた変数にreturn値を割り当てて使用する必要があります(理由は以下参照)。
delq関数がリストの銭湯にある要素を削除する場合は、単にリストを読み進めて、この要素の後から開始される部分リストをreturnします。つまり:
(delq 'a '(a b c)) ≡ (cdr '(a b c))
リストの途中にある要素を削除するときは、必要なCDR(Setcdrを参照してください)を変更することにより削除します。
(setq sample-list '(a b c (4)))
⇒ (a b c (4))
(delq 'a sample-list)
⇒ (b c (4))
sample-list
⇒ (a b c (4))
(delq 'c sample-list)
⇒ (a b (4))
sample-list
⇒ (a b (4))
(delq 'a sample-list)は何も取り除きませんが(これは単に短いリストをreturnします)、(delq 'c
sample-list)は3番目の要素を取り除いて、sample-listを変更することに注意してください。引数listを保持するように形成された変数が、実行後にもっと少ない要素になる、または元のリストを保持すると仮定しないでください!
かわりにdelqの結果を保存して、それを使用してください。元のリストを保持していた変数に、結果を書き戻すことはよく行なわれます。
(setq flowers (delq 'rose flowers))
以下の例では、delqが比較しようとしている(4)と、sample-list内の(4)は、eqではありません:
(delq '(4) sample-list)
⇒ (a c (4))
与えられた値とequalな要素を削除したい場合は、delete(以下参照)を使用してください。
この関数は、objectとeqなすべての要素が除かれた、listのコピーをreturnします。remqの文字‘q’は、この関数がobjectとリスト内の要素の比較に、eqを使用することを示します。
(setq sample-list '(a b c a b c))
⇒ (a b c a b c)
(remq 'a sample-list)
⇒ (b c b c)
sample-list
⇒ (a b c a b c)
関数memqlは、eql(浮動少数の要素は値で比較される)を使用してメンバーとeqlを比較することにより、objectがlistのメンバーかどうかをテストします。objectがメンバーの場合、memqlはlist内で最初に見つかった要素から開始されるリストをreturnします。それ以外はnilをreturnします。
これをmemqと比較してみましょう:
(memql 1.2 '(1.1 1.2 1.3)) ; 1.2と1.2はeql。
⇒ (1.2 1.3)
(memq 1.2 '(1.1 1.2 1.3)) ; 1.2と1.2はeqではない。
⇒ nil
以下の3つの関数はmemq、delq、remqと似ていますが、要素の比較にeqではなく、equalを使用します。Equality Predicatesを参照してください。
関数memberは、メンバーとobjectをequalを使用して比較して、objectがlistのメンバーかどうかをテストします。objectがメンバーの場合、memberはlistで最初に見つかったところから開始されるリストをreturnします。それ以外はnilを参照してください。
これをmemqと比較してみましょう:
(member '(2) '((1) (2))) ; (2) and (2) are equal.
⇒ ((2))
(memq '(2) '((1) (2))) ; (2)と(2)はeqではない。
⇒ nil
;; 同じ内容の2つの文字列はequal。
(member "foo" '("foo" "bar"))
⇒ ("foo" "bar")
この関数は、sequenceからobjectとequalな要素を取り除いて、結果のシーケンスをreturnします。
sequenceがリストの場合、deleteがdelqに対応するように、memberはmemqに対応します。つまり、この関数はmemberと同様、要素とobjectの比較にequalを使用します。マッチする要素が見つかったら、delqが行なうように、その要素を取り除きます。delqと同様、通常は元のリストを保持していた変数にreturn値を割り当てて使用します。
sequenceがベクターまたは文字列の場合、deleteはobjectとequalなすべての要素を取り除いた、sequenceのコピーをreturnします。
たとえば:
(setq l '((2) (1) (2)))
(delete '(2) l)
⇒ ((1))
l
⇒ ((2) (1))
;; lの変更に信頼性を要するときは
;; (setq l (delete '(2) l))と記述する。
(setq l '((2) (1) (2)))
(delete '(1) l)
⇒ ((2) (2))
l
⇒ ((2) (2))
;; このケースではlのセットの有無に違いはない
;; しかし他のケースに倣ってセットするべき。
(delete '(2) [(2) (1) (2)])
⇒ [(1)]
この関数は、deleteに対応する非破壊的な関数です。この関数は、objectとequalな要素を取り除いた、sequence(リスト、ベクター、文字列)のコピーをreturnします。たとえば:
(remove '(2) '((2) (1) (2)))
⇒ ((1))
(remove '(2) [(2) (1) (2)])
⇒ [(1)]
Common Lispに関する注意: GNU Emacs Lispの関数
member、delete、removeは、Common Lispではなく、Maclispを継承しています。Common Lispでは、比較にequalを使用しません。
この関数は、memberと同様ですが、objectが文字列で、大文字小文字とテキスト表現の違いを無視します。文字の大文字と小文字は等しいものとして扱われ、比較に先立ちユニバイト文字列はマルチバイト文字列に変換されます。
この関数は、listからすべてのequalな重複を、破壊的に取り除いて。、結果をlistに保管して、それをreturnします。list内の要素にequalな要素がいくつかある場合、delete-dupsは最初の要素を残します。
変数に格納されたリストに要素を追加したり、それを集合として使用する方法については、List Variablesの関数add-to-listも参照してください。
Next: Association Lists, Previous: Modifying Lists, Up: Lists [Contents][Index]