Emacs Lisp: Association List
Association List (aka alist) is a value type in Emacs Lisp.
Association List is a
List
, where each element is a
Cons Pair
, like this
(key . val)
.
- In each cons pair, the key and value can be any value type.
- Items in Association List can have duplicate keys, and order is maintained.
What is the Difference Between Association List and Hash Table?
- Association List is ordered. Hash Table items are not.
- Association List can have duplicate keys. Hash Table keys are unique.
- Association List access time is proportional to number of items. Hash Table is constant time to access any item regardless of number of items.
- Association List entries are hard to modify. As a list, it's designed to only add or drop first item of the list. Hash Table entries are designed to be modified, or added or deleted.
Create a Alist
Using string as key:
(setq xx '(("aa" . 23) ("bb" . 24) ("cc" . 33)))
Using Symbol as key:
(setq xx '((aa . 23) (bb . 24) (cc . 33)))
Symbol Key vs String Key
Usually,
Symbol
is used for key.
eq
tests if 2 symbols are equal.
You can also use
String
as key. To compare if 2 string is equal, equal
works.
Some functions for alist use eq
to test existence of key, and others use equal
.
Some lets you specify a function for equality test.
So, it is important to know:
- What datatype you are using as key in your alist
- Which equality test is used by a specific alist function.
Get Value by Key
alist-get
-
(alist-get key alist &optional default remove testfn)
Return the first value of the key. If no exist, return default or nil.the remove should be nil. (it is used in advanced situation with
setf
. you shouldn't use that for beginning lisp. See doc.)key existence is checked by testfn (must be a symbol of function). Default to
eq
. [see Emacs Lisp: Test Equality](setq xx '(("aa" . 23) ("bb" . 24) ("cc" . 33))) ;; get the value with key "bb". if not found, return 999. use string-equal for comparison (alist-get "bb" xx 999 nil 'string-equal) ;; 24 (alist-get "dd" xx 999 nil 'string-equal) ;; 999
(setq xx '((aa . 23) (bb . 24) (cc . 33))) ;; get the value with symbol key bb. if not found, return 999 (alist-get 'bb xx 999) ;; 24 (alist-get 'dd xx 999) ;; 999
Get Pair by Key
assoc
-
(assoc key alist)
Return the first pair with the key. If no exist, return nil. (key existence is checked byequal
. [see Emacs Lisp: Test Equality] )(setq xx '(("aa" . 23) ("bb" . 24) ("cc" . 33))) ;; get the pair with key "bb" (assoc "bb" xx) ; return ("bb" . 24)
assq
-
(assq key alist)
same asassoc
except key is checked byeq
. Use this if all keys are Symbols [see Emacs Lisp: Test Equality](setq xx '((aa . 23) (bb . 24) (cc . 33))) (assq 'aa xx)
Check If a Key Exist
Use assoc
or assq
.
Get Pair by Value
You can search alist by value.
rassoc
-
(rassoc val alist)
Return the first pair that has specific value. Else return nil. Test is done byequal
. [see Emacs Lisp: Test Equality](setq xx '(("aa" . 23) ("bb" . 24) ("cc" . 33))) ;; get the pair with value 24 (rassoc 24 xx) ; return ("bb" . 24)
rassq
-
(rassq value alist)
same asrassoc
except value is compared usingeq
. [see Emacs Lisp: Test Equality]
Add a Element
Add a Pair to Front
Add a element to the front. Use push
(setq xx '(("aa" . 23) ("bb" . 24) )) ;; add a element (push '("cc" . 33) xx)
Add a Pair If Key No Exist
(setq xx '(("aa" . 23) ("bb" . 24) )) (when (not (assoc "cc" xx)) (push '("cc" . 33) xx))
Add a Pair If Pair No Exist
(defun xah-add-asso-if-pair-no-exist (ConsPair Alist) "Add ConsPair to Alist if the ConsPair not exist. Both key and value of ConsPair are checked. With `equal'. Return Alist. Version 2021-12-03" (interactive) (let* (($key (car ConsPair)) ($val (cdr ConsPair)) ($result (assoc $key Alist))) (if (and $result (equal $val (cdr $result))) nil (push ConsPair Alist)) Alist )) ;; sample usage (xah-add-asso-if-pair-no-exist '("aa" . 23) '(("aa" . 23) ("bb" . 24))) ;; not added (xah-add-asso-if-pair-no-exist '("aa" . 99) '(("aa" . 23) ("bb" . 24))) ;; added
Delete Pairs by Key
assoc-delete-all
(assoc-delete-all KEY ALIST &optional TEST)
Delete all elements that has key KEY. Keys are checkd by TEST. Defaults toequal
. Return the modified alist. Elements of ALIST that are not conses are ignored.(setq xx '(("aa" . 23) ("bb" . 24) )) (setq xx (assoc-delete-all "bb" xx))
assq-delete-all
-
same as
assoc-delete-all
but useseq
for testing key.
More Alist Functions
Note, Association List is a List , any function that works on list also works on Association List.
[see Emacs Lisp: Sequence Functions]
There are many more specialized function for alist. See
(info "(elisp) Association Lists")