Elisp: Association List
What is Association List
Association List (aka alist) is a List , where each element is a Cons Pair , like this
(cons key value)
- 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.
Difference Between Association List and Hash Table
- Association List is ordered. Hash Table is 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.
Difference Between List of Pairs and Association List
Dot Notation for Cons
when creating a association list, For example
(list
(cons k1 v1)
(cons k2 v2)
)
if you do not need to evaluate the items, you can write it as
'(
(k1 . v1)
(k2 . v2)
)
Create a Alist
String key example
;; example of association list (setq xx (list (cons "aa" 23) (cons "bb" 24) (cons "cc" 33))) ;; dot notation (setq xx '(("aa" . 23) ("bb" . 24) ("cc" . 33)))
Symbol key example
;; example of association list ;; where keys are symbols, values are numbers (setq xx (list (cons 'aa 23) (cons 'bb 24) (cons 'cc 33))) ;; dot notation (setq xx '((aa . 23) (bb . 24) (cc . 33)))
Symbol Key vs String Key
- Keys can be Symbol type.
eq
tests if 2 symbols are equal. - Keys can be String type.
equal
tests if 2 strings are equal.
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.
💡 TIP: I recommend using string as keys whenever possible. Because that is simpler. Using symbol key pollutes the symbol table obarray. Use symbol key only when you need to work with lisp function names or variable names.
〔see Elisp: Equality Test〕
Get Value by Key
alist-get
-
(alist-get key alist &optional default remove testfn)
Find the first key, return its value. If no exist, return default. Default to
nil
.The remove should be
nil
. (it is used in advanced situation with Place Expression . Best to avoid. )key existence is checked by testfn (must be a symbol of function). Default to
eq
. 〔see Elisp: Equality Test〕(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 Cons Cell by Key
assoc-string
-
(assoc-string KEY LIST &optional CASE-FOLD)
Designed specifically for association list of string keys.
- Return the first cons cell (or atom) with the key.
- If no exist, return
nil
. - Element in the list can be just a string or symbol, instead of a Cons Cell.
- Works also if keys are symbol type.
- When doing the comparison, symbols are first converted to strings, and unibyte strings to multibyte.
- CASE-FOLD is
t
ornil
. Ift
, both KEY and the elements of LIST are upcased for comparison.
(setq xx (list (cons "aa" 23) (cons "bb" 24) (cons "cc" 33))) ;; get the cons cell with key "bb" (assoc-string "bb" xx) ;; ("bb" . 24)
;; demo assoc-string, showing the list element needs not be a cons cell (setq xx (list (cons "aa" 23) "bb" (cons "cc" 33))) ;; get the cons cell with key "bb" (assoc-string "bb" xx) ;; "bb"
assoc
-
(assoc key alist)
- Return the first cons cell with the key.
- If no exist, return
nil
. - Key existence is checked by
equal
. 〔see Elisp: Equality Test〕
💡 TIP: use this if all keys are symbols, or strings, or integers.
(setq xx (list (cons "aa" 23) (cons "bb" 24) (cons "cc" 33))) ;; get the cons cell with key "bb" (assoc "bb" xx) ;; ("bb" . 24)
assq
-
(assq key alist)
similar to
assoc
except key is checked byeq
.〔see Elisp: Equality Test〕
💡 TIP: use this if all keys are symbols, or integers.
(setq xx '((aa . 23) (bb . 24) (cc . 33))) (assq 'aa xx)
Check If a Key Exist
Use assoc
or assq
.
Get Cons Cell by Value
You can search alist by value.
rassoc
-
(rassoc value alist)
- Return the first cons cell that has specific value.
- Else return
nil
. - Test is done by
equal
. 〔see Elisp: Equality Test〕
(setq xx '(("aa" . 23) ("bb" . 24) ("cc" . 33))) ;; get the cons cell with value 24 (rassoc 24 xx) ; return ("bb" . 24)
rassq
-
(rassq value alist)
similar to
rassoc
except value is compared usingeq
. 〔see Elisp: Equality Test〕
Add Item
Add a Item to Front
Add a element to the front. Use push
(setq xx '(("aa" . 23) ("bb" . 24) )) ;; add a element (push '("cc" . 33) xx)
Add Item If Key No Exist
(setq xx '(("aa" . 23) ("bb" . 24) )) (when (not (assoc "cc" xx)) (push '("cc" . 33) xx))
Delete Items by Key
assoc-delete-all
-
(assoc-delete-all KEY ALIST &optional TEST)
- Delete all elements that has key KEY.
- Keys are checked by TEST. Defaults to
equal
. - Return the modified alist.
- Elements of ALIST that are not
cons
are ignored.
(setq xx '(("aa" . 23) ("bb" . 24) )) (setq xx (assoc-delete-all "bb" xx))
assq-delete-all
-
similar to
assoc-delete-all
but useseq
for testing key.
Delete Item by Value
rassq-delete-all
-
(rassq-delete-all VALUE ALIST)
- Delete all elements whose value matches.
- values are checked by
eq
. - Return the modified alist.
- Elements of ALIST that are not
cons
are ignored.
(setq xx (list (cons "aa" 3) (cons "bb" 4) (cons "cc" 4) (cons "dd" 5))) (rassq-delete-all 4 xx) ;; (("aa" . 3) ("dd" . 5))
More Alist Functions
- Association List is a List. Any function that works on list also works on Association List.
- List is a subset of Sequence Type. Any function that work on sequence also works on association list. See Elisp: Sequence Functions
here are more specialized function for alist.
assoc-default
-
(assoc-default KEY ALIST &optional TEST DEFAULT)
Designed for list whose element can be either Cons Cell or not. And valid match is considered only if element is cons cell. Return the
cdr
part of match.- If a match is found, return
cdr
ofcons
if the item iscons
, else return DEFAULT. - If no match, return
nil
.
- A match is determined by the function
TEST
. TEST
is given two argumentsitem
andKEY
, in that order.item
is either thecar
ofcons
, or the element itself if it's not a cons cell.
- by default,
TEST
isequal
.
;; demo assoc-default (setq xx (list (cons "aa" 2) "bb" (cons "bb" 3) (cons "cc" 4) (list "dd" 5))) ;; match found, return its cdr (assoc-default "aa" xx ) ;; 2 ;; match found, return its cdr (assoc-default "dd" xx ) ;; (5) ;; match found, but bb is not a cons, so return nil (assoc-default "bb" xx ) ;; nil ;; no match (assoc-default "ee" xx ) ;; nil
- If a match is found, return
copy-alist
let-alist
Emacs Lisp, list
- Elisp: List
- Elisp: Create List
- Elisp: List, Get Elements
- Elisp: Modify List
- Elisp: List Iteration
- Elisp: Check Element Exist in List
- Elisp: Remove Elements in List
- Elisp: Sequence. Join, Convert
- Elisp: Backquote Reader Macro for List