Next: , Previous: Modifying Lists, Up: Lists


5.7 集合としてのリストの利用

リストで、数学の順序のない集合を表現できます。 つまり、リストに現れる要素を集合の要素と考え、 リスト内での順序は無視します。 2つの集合の和集合を作るには、 (要素が重複することを気にしなければ)appendを使います。 集合向けの他の有用な関数には、memqdelq、および、 これらのequal版であるmemberdeleteがあります。

Common Lispに関した注意: Common Lispには、集合演算向けに (要素の重複を避ける)関数unionintersectionがあるが、 GNU Emacs Lispにはない。 必要ならば、読者みずからLispでこれらを書ける。
— Function: memq object list

この関数は、objectlistの要素かどうか調べる。 そうならば、 memqobjectが最初に現れるところから始まるリストを返す。 さもなければnilを返す。 memqの文字‘q’は、リストの要素に対するobjectの比較に eqを使うことを意味する。 たとえば、

          (memq 'b '(a b c b a))
               ⇒ (b c b a)
          
          (memq '(2) '((1) (2)))    ; (2)(2)eqではない
               ⇒ nil
— Function: delq object list

この関数は、listからobjecteqであるすべての要素を 破壊的に削除する。 delqの文字‘q’は、memqと同様に、 リストの要素に対するobjectの比較にeqを使うことを意味する。

delqがリストの先頭から要素を削除する場合には、 単にリストを辿って削除した要素のつぎから始まる部分リストを返します。

     (delq 'a '(a b c)) == (cdr '(a b c))

リストの中ほどの要素を削除する場合には、 削除にはcdrの変更を伴います(see 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 'c sample-list)は、 3番目の要素を切り取ってsample-listを変更しますが、 (delq 'a sample-list)では、 なにも切り取らずに単に短いリストを返すことに注意してください。 引数listを保持していた変数が、実行後には少ない要素を持つと仮定したり、 もとのリストを保持し続けていると仮定したりしないでください! そのかわりに、delqの結果を保存して、それを使ってください。 多くの場合、つぎのように、 もとのリストを保持していた変数に結果を保存し直します。

     (setq flowers (delq 'rose flowers))

つぎの例では、delqが一致を取ろうとしている(4)sample-list(4)とはeqではありません。

     (delq '(4) sample-list)
          ⇒ (a c (4))

つぎの2つの関数は、memqdelqに似ていますが、 比較にはeqのかわりにequalを使います。 See Equality Predicates

— Function: member object list

関数memberは、equalを使ってobjectと要素を比較して、 objectlistの要素かどうか調べる。 objectが要素であれば、 memberlist内でそれが最初に現れるところから始まるリストを返す。 さもなければnilを返す。

memqと比較してほしい。

          
          (member '(2) '((1) (2)))  ; (2)(2)equalである
               ⇒ ((2))
          
          (memq '(2) '((1) (2)))    ; (2)(2)eqではない
               ⇒ nil
          
          ;; 同じ内容の2つの文字列はequalである
          (member "foo" '("foo" "bar"))
               ⇒ ("foo" "bar")
— Function: delete object list

この関数は、listからobjectequalであるすべての要素を 破壊的に削除する。 membermemeqに対応するように、delqに対応する。 memberと同様に、 要素とobjectとの比較にはequalを使う。 一致する要素をみつけると、delqと同様に要素を削除する。 たとえば、つぎのとおり。

          (delete '(2) '((2) (1) (2)))
               ⇒ ((1))
Common Lispに関した注意: GNU Emacs Lispの関数memberと関数deleteは Maclispから受け継いだものであり、Common Lispからではない。 Common Lisp版では要素の比較にはequalを使わない。

変数に格納したリストに要素を追加する別の方法については、 Setting Variablesの関数add-to-listを参照してください。