Emacs Lisp: Association List
Associative List (aka “alist”) is a datatype in Emacs Lisp.
Alist is a list, where each element is a cons pair, like this
(cons key value).
(cons a b)
can also be written as
(a . b).
In each cons pair, the key and value can be any datatype.
Items in alist can have duplicate keys, and order is maintained.
Note: elisp also has true hash table.
〔►see Emacs Lisp: Hash Table〕
What's the Difference Between Alist and Hash Table?
- Alist is a list, meaning, items are ordered, and can have duplicate keys.
- Hash Table entries are unique. Hash Table items are not ordered. Hash Table is usually faster for random access when there are huge number of items (tens of thousands).
- Alist has literal form. That is, you can create it by for example,
(list (cons 1 2) (cons 3 4)). Hashtable does not have a literal form. You have to create a hash table, and use a function to add each key/value pair.
Create a Alist
Because alist is a list, any function that works on list also works on alist.
〔►see Emacs Lisp: List〕
;; set x to a alist (setq x '(("mary" . 23) ("john" . 24) ("smith" . 33)))
There are functions that's designed for working with alist. For example, get the pair of a given key. or get the pair of a given value.
Here's the most useful functions for working with alist.
Get Pair by Key
assoc to get the pair of a given key. It returns the first found pair with the key. If the alist does not have the key, returns
(the key existence is checked by using
(assoc key alist)
;; set x to a alist (setq x '(("mary" . 23) ("john" . 24) ("smith" . 33))) ;; get the pair with key "john" (assoc "john" x) ; returns ("john" . 24)
After you got the cons pair, you can use
car to get the first element, and use
cdr to get the last element.
;; set x to a alist (setq x '(("mary" . 23) ("john" . 24) ("smith" . 33))) ;; get the value with key "john" (cdr (assoc "john" x)) ; returns 24
Get Pair by Value
You can search alist by value.
(rassq value alist)
returns the first association with value value in alist. It returns
nil if no association in alist has a CDR
eq to value.
;; set x to a alist (setq x '(("mary" . 23) ("john" . 24) ("smith" . 33))) ;; get the pair with value 24 (rassoc 24 x) ; returns ("john" . 24)