Next: Property Lists, Previous: Sets And Lists, Up: Lists [Contents][Index]
連想配列(association list。短くはalist)は、キーと値のマッピングを記録します。これは連想(associations)と呼ばれるコンスセルのリストです。各コンスセルにおいて、CARはキー(key)で、CDRは連想値(associated value)になります。3
以下はalistの例です。キーpine
は、値cones
に関連付けられます。キーoak
は、acorns
に関連付けられます。キーmaple
は、seeds
に関連付けられます。
((pine . cones) (oak . acorns) (maple . seeds))
alist内の値とキーには、任意のLispオブジェクトを指定できます。たとえば以下のalist0では、シンボルa
は数字1
に、文字列"b"
はリスト(2
3)
(alist要素のCDR)に関連付けられます。
((a . 1) ("b" 2 3))
要素のCDRのCARに連想値を格納するようにalistデザインするほうがよい場合があります。以下は、そのようなalistです。
((rose red) (lily white) (buttercup yellow))
この例では、red
がrose
に関連付けられる値だと考えます。この種のalistの利点は、CDRのCDRの中に、他の関連する情報
— 他のアイテムのリストでさえ —
を格納することができることです。不利な点は、与えられた値を含む要素を見つけるためにrassq
(以下参照)を使用できないことです。これらを検討することが重要でない場合には、任意の与えられたalistにたいして一貫している限り、選択は好みの問題といえます。
上記で示したのと同じalistは、要素のCDRに連想値をもつと考えることができます。この場合、rose
に関連付けられる値は、リスト(red)
になるでしょう。
連想リストは、新しい連想を簡単にリストの先頭に追加できるので、スタックに保持したいような情報を記録するのによく使用されます。連想リストから与えられたキーにたいする連想を検索する場合、それが複数ある場合は、最初に見つかったものがreturnされます。
Emacs Lispでは、連想リストがコンスセルではない場合、それはエラーではありません。alist検索関数は、単にそのような要素を無視します。多くの他のバージョンのLいspでは、このような場合はエラーをシグナルします。
いくつかの観点において、プロパティーリストは連想リストと似ていることに注意してください。それぞれのキーが1度だけ出現するような場合、プロパティーリストは連想リストと同様に振る舞います。プロパティーリストと連想リストの比較については、Property Listsを参照してください。
この関数は、alist要素にたいしてkeyを比較するのにequal
を使用して、alist内からkeyをもつ最初の連想をreturnします。CARがkeyとequal
の連想がalistにない場合、この関数はnil
をreturnします。たとえば:
(setq trees '((pine . cones) (oak . acorns) (maple . seeds))) ⇒ ((pine . cones) (oak . acorns) (maple . seeds)) (assoc 'oak trees) ⇒ (oak . acorns) (cdr (assoc 'oak trees)) ⇒ acorns (assoc 'birch trees) ⇒ nil
以下はキーと値がシンボルでない場合の例です:
(setq needles-per-cluster '((2 "Austrian Pine" "Red Pine") (3 "Pitch Pine") (5 "White Pine"))) (cdr (assoc 3 needles-per-cluster)) ⇒ ("Pitch Pine") (cdr (assoc 2 needles-per-cluster)) ⇒ ("Austrian Pine" "Red Pine")
関数assoc-string
はassoc
と似ていますが、文字列間の特定の違いを無視する点が異なります。Text Comparisonを参照してください。
この関数は、alistの中から、値valueをもつ最初の連想をreturnします。CDRがvalueとequal
の連想がalistにない場合、この関数はnil
をreturnします。
rassoc
はassoc
と似ていますが、CARではなく、alistの連想のCDRを比較します。この関数を、与えられた値に対応するキーを探す、“reverse
assoc
”と考えることができます。
この関数は、alistからkeyをもつ最初の連想をreturnする点はassoc
と同様ですが、比較にequal
ではなくeq
を使用します。CARがkeyとeq
な連想がalist内に存在しない場合、assq
はnil
をreturnします。eq
はequal
より早く、ほとんどのalistはキーにシンボルを使用するので、この関数はassoc
より多用されます。Equality Predicatesを参照してください。
(setq trees '((pine . cones) (oak . acorns) (maple . seeds))) ⇒ ((pine . cones) (oak . acorns) (maple . seeds)) (assq 'pine trees) ⇒ (pine . cones)
反対に、キーがシンボルではないalistでは通常、assq
は有用ではありません:
(setq leaves '(("simple leaves" . oak) ("compound leaves" . horsechestnut))) (assq "simple leaves" leaves) ⇒ nil (assoc "simple leaves" leaves) ⇒ ("simple leaves" . oak)
この関数は、alist内から値valueをもつ最初の連想をreturnします。alist内にCDRがvalueとeq
な連想が存在しない場合は、nil
をreturnします。
rassq
はassq
と似ていますが、CARではなく、alistの各連想のCDRを比較します。この関数を、与えられた値に対応するキーを探す、“reverse
assq
”と考えることができます。
たとえば:
(setq trees '((pine . cones) (oak . acorns) (maple . seeds))) (rassq 'acorns trees) ⇒ (oak . acorns) (rassq 'spores trees) ⇒ nil
rassq
は、要素のCDRのCARに保管された値の検索はできません:
(setq colors '((rose red) (lily white) (buttercup yellow))) (rassq 'white colors) ⇒ nil
この場合、連想(lily
white)
のCDRはwhite
ではなく、リスト(white)
です。これは連想をドットペア表記で記述すると明確になります:
(lily white) ≡ (lily . (white))
この関数は、keyにたいするマッチをalistから検索します。alistの各要素にたいして、この関数は、keyと要素(アトムの場合)、または要素のCAR(コンスの場合)を比較します。比較はtestに2つの引数
— 要素(または要素のCAR)とkey —
を与えて呼び出すことにより行なわれます。引数はこの順番で渡されるので、正規表現(Regexp Searchを参照してください)を含むalistでは、string-match
を使用することにより有益な結果を得ることができます。testが省略されているかnil
の場合は、比較にequal
が使用されます。
alistの要素がこの条件によりkeyとマッチした場合、assoc-default
はこの要素の値をreturnします。要素がコンスの場合、値は要素のCDRです。それ以外の場合、return値はdefaultです。
keyにマッチする要素がalistに存在しない場合、assoc-default
はnil
をreturnします。
この関数は、深さ2がレベルのalistのコピーをreturnします。この関数は各連想の新しいコピーを作成するので、元のalistを変更せずに、新しいalistを変更できます。
(setq needles-per-cluster '((2 . ("Austrian Pine" "Red Pine")) (3 . ("Pitch Pine"))
(5 . ("White Pine")))) ⇒ ((2 "Austrian Pine" "Red Pine") (3 "Pitch Pine") (5 "White Pine")) (setq copy (copy-alist needles-per-cluster)) ⇒ ((2 "Austrian Pine" "Red Pine") (3 "Pitch Pine") (5 "White Pine")) (eq needles-per-cluster copy) ⇒ nil (equal needles-per-cluster copy) ⇒ t (eq (car needles-per-cluster) (car copy)) ⇒ nil (cdr (car (cdr needles-per-cluster))) ⇒ ("Pitch Pine")
(eq (cdr (car (cdr needles-per-cluster))) (cdr (car (cdr copy)))) ⇒ t
以下の例は、どのようにしてcopy-alist
が他に影響を与えずにコピーの連想を変更可能なのかを示します:
(setcdr (assq 3 copy) '("Martian Vacuum Pine")) (cdr (assq 3 needles-per-cluster)) ⇒ ("Pitch Pine")
この関数は、alistから、(delq
を使用した場合は、そのような要素を1つずつ削除するのにたいして)CARがkeyとeq
な要素すべてを削除します。この関数は短くなったalistをreturnし、alistの元のリスト構造を変更することもよくあります。正しい結果を得るために、alistに保存された値ではなく、assq-delete-all
のreturn値を使用してください。
(setq alist '((foo 1) (bar 2) (foo 3) (lose 4))) ⇒ ((foo 1) (bar 2) (foo 3) (lose 4)) (assq-delete-all 'foo alist) ⇒ ((bar 2) (lose 4)) alist ⇒ ((foo 1) (bar 2) (lose 4))
この関数は、alistからCDRがvalueとeq
なすべての要素を削除します。この関数は短くなったリストをreturnし、alistの元のリスト構造を変更することもよくあります。rassq-delete-all
はassq-delete-all
と似ていますが、CARではなくalistの各連想のCDRを比較します。
ここでの“キー(key)”の使い方は、用語“キーシーケンス(key sequence)”とは関係ありません。キーはテーブルにあるアイテムを探すために使用される値という意味です。この場合、テーブルはalistでありalistはアイテムに関連付けられます。
Next: Property Lists, Previous: Sets And Lists, Up: Lists [Contents][Index]