An association list, or alist for short, records a mapping from keys to values. It is a list of cons cells called associations: the CAR of each cons cell is the key, and the CDR is the associated value.(1)
Here is an example of an alist. The key pine
is associated with
the value cones
; the key oak
is associated with
acorns
; and the key maple
is associated with seeds
.
'((pine . cones) (oak . acorns) (maple . seeds))
The associated values in an alist may be any Lisp objects; so may the
keys. For example, in the following alist, the symbol a
is
associated with the number 1
, and the string "b"
is
associated with the list (2 3)
, which is the CDR of
the alist element:
((a . 1) ("b" 2 3))
Sometimes it is better to design an alist to store the associated value in the CAR of the CDR of the element. Here is an example:
'((rose red) (lily white) (buttercup yellow))
Here we regard red
as the value associated with rose
. One
advantage of this kind of alist is that you can store other related
information--even a list of other items--in the CDR of the
CDR. One disadvantage is that you cannot use rassq
(see
below) to find the element containing a given value. When neither of
these considerations is important, the choice is a matter of taste, as
long as you are consistent about it for any given alist.
Note that the same alist shown above could be regarded as having the
associated value in the CDR of the element; the value associated
with rose
would be the list (red)
.
Association lists are often used to record information that you might otherwise keep on a stack, since new associations may be added easily to the front of the list. When searching an association list for an association with a given key, the first one found is returned, if there is more than one.
In Emacs Lisp, it is not an error if an element of an association list is not a cons cell. The alist search functions simply ignore such elements. Many other versions of Lisp signal errors in such cases.
Note that property lists are similar to association lists in several respects. A property list behaves like an association list in which each key can occur only once. See section Property Lists, for a comparison of property lists and association lists.
equal
(see section Equality Predicates). It returns nil
if no
association in alist has a CAR equal
to key.
For example:
(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
Here is another example, in which the keys and values are not symbols:
(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")
The functions assoc-ignore-representation
and
assoc-ignore-case
are much like assoc
except using
compare-strings
to do the comparison. See section Comparison of Characters and Strings.
nil
if no association in alist has
a CDR equal
to value.
rassoc
is like assoc
except that it compares the CDR of
each alist association instead of the CAR. You can think of
this as "reverse assoc
", finding the key for a given value.
assoc
in that it returns the first
association for key in alist, but it makes the comparison
using eq
instead of equal
. assq
returns nil
if no association in alist has a CAR eq
to key.
This function is used more often than assoc
, since eq
is
faster than equal
and most alists use symbols as keys.
See section Equality Predicates.
(setq trees '((pine . cones) (oak . acorns) (maple . seeds))) => ((pine . cones) (oak . acorns) (maple . seeds)) (assq 'pine trees) => (pine . cones)
On the other hand, assq
is not usually useful in alists where the
keys may not be symbols:
(setq leaves '(("simple leaves" . oak) ("compound leaves" . horsechestnut))) (assq "simple leaves" leaves) => nil (assoc "simple leaves" leaves) => ("simple leaves" . oak)
nil
if no association in alist has
a CDR eq
to value.
rassq
is like assq
except that it compares the CDR of
each alist association instead of the CAR. You can think of
this as "reverse assq
", finding the key for a given value.
For example:
(setq trees '((pine . cones) (oak . acorns) (maple . seeds))) (rassq 'acorns trees) => (oak . acorns) (rassq 'spores trees) => nil
Note that rassq
cannot search for a value stored in the CAR
of the CDR of an element:
(setq colors '((rose red) (lily white) (buttercup yellow))) (rassq 'white colors) => nil
In this case, the CDR of the association (lily white)
is not
the symbol white
, but rather the list (white)
. This
becomes clearer if the association is written in dotted pair notation:
(lily white) == (lily . (white))
string-match
with an alist that contains
regular expressions (see section Regular Expression Searching). If test is omitted
or nil
, equal
is used for comparison.
If an alist element matches key by this criterion,
then assoc-default
returns a value based on this element.
If the element is a cons, then the value is the element's CDR.
Otherwise, the return value is default.
If no alist element matches key, assoc-default
returns
nil
.
(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
This example shows how copy-alist
makes it possible to change
the associations of one copy without affecting the other:
(setcdr (assq 3 copy) '("Martian Vacuum Pine")) (cdr (assq 3 needles-per-cluster)) => ("Pitch Pine")
Go to the first, previous, next, last section, table of contents.