ELisp: Association List

By Xah Lee. Date: . Last updated: .

What is Association List

Association List (aka alist) is a List , where each element is a Cons Pair , like this

(cons key val)

What is the Difference Between Association List and Hash Table?

Tip: 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) )

[see ELisp: Quote and Dot Notation]

Create a Alist

Using string as key:

;; 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)))

Using Symbol as key:

;; 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

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:

[see ELisp: Equality Test]

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 Place Expression . You shouldn't use that for beginning lisp.)

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 Pair by Key

assoc
(assoc key alist)
Return the first pair with the key. If no exist, return nil. (key existence is checked by equal. [see ELisp: Equality Test] )
(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 as assoc except key is checked by eq. Use this if all keys are Symbols [see ELisp: Equality Test]
(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 by equal. [see ELisp: Equality Test]
(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 as rassoc except value is compared using eq. [see ELisp: Equality Test]

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 new Alist.
Version 2021-12-03"
  (let* ((xkey (car ConsPair))
         (xval (cdr ConsPair))
         (xresult (assoc xkey Alist)))
    (if (and xresult (equal xval (cdr xresult)))
        nil
      (push ConsPair Alist))
    Alist
    ))

;; HHHH---------------------------------------------------

;; sample usage

(xah-add-asso-if-pair-no-exist
 (cons "aa" 23)
 (list (cons "aa" 23)
       (cons "bb" 24)))
;; not added

(xah-add-asso-if-pair-no-exist
 (cons "aa" 99)
 (list (cons "aa" 23)
       (cons "bb" 24)))
;; added

;; HHHH---------------------------------------------------
;; sample usage with dot notation

(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 to equal. 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 uses eq for testing key.

More Alist Functions

Note, Association List is a List , any function that works on list also works on Association List.

[see ELisp: Sequence Functions]

There are many more specialized function for alist. See

Association Lists (ELISP Manual)

Emacs Lisp List

Special Lists

List Structure