Emacs Lisp: Hash Table

By Xah Lee. Date: . Last updated: .

Emacs lisp has 2 types of collection of key/value pairs.

Association List (aka alist).
A ordered list of key val pairs. Keys may repeat.
Hash Table.
Unordered set of key val pairs. No duplicate keys. Constant access time.

Create Hash Table

(make-hash-table :test 'equal)
Returns a new hashtable. The :test 'equal is to specify what function to use to test key existence. For example, if your keys are integers or lisp symbols, you can use :test eq. If your keys are strings, you must use :test equal, because (eq "x" "x") returns nil.
Key or Value can be any lisp object (aka datatype).
There are more options for make-hash-table. Alt+x describe-function for detail.
;; create a hash table
(setq myHash (make-hash-table :test 'equal))

Literal Expression for Hashtable

You can create a hash table by a literal expression, like this:

(setq myHash
      #s(hash-table
         size 30
         test equal
         data (
               "joe" 3
               "jane" 9
               "liz" 5 )))

;; test
(gethash "joe" myHash ) ; 3

(info "(elisp) Creating Hash")

Add Entry

(puthash "joe" 19 myHash)

Remove Entry

(remhash "liz" myHash)

Check Key Exist

(gethash key table)
if a key exist, return key's value. Else, return nil
(gethash key table default)
Return default if key does not exist.
(let ((myHash (make-hash-table :test 'equal)))
  (puthash 'aa 9 myHash)
  (gethash 'bb myHash)    ; ⇒ nil
  (gethash 'bb myHash 10) ; ⇒ 10
  )

Get Key's Value

(gethash "jane" myHash)

Number of Entries

(hash-table-count myHash)

Remove All Entries

(clrhash myHash)

Apply a Function to All Entries

(maphash f hashtable)
Apply a function to all entries in a hash table. The function f must take 2 arguments, key and value.
(setq myHash (make-hash-table :test 'equal))
(puthash "joe" 19 myHash)
(puthash "jane" 20 myHash)
(puthash "carrie" 17 myHash)
(puthash "liz" 21 myHash)

(maphash
   (lambda (k v)
     (princ (format "%s , %s" k v))
     (princ "\n"))
   myHash
   )

Get All Keys

(hash-table-keys hash)
Return a list of keys in HASH-TABLE. (require 'subr-x) New in emacs 24.4
;; get all keys from a hash table

(setq myHash
      #s(hash-table
         size 30
         test equal
         data (
               "joe" 3
               "jane" 9
               "liz" 5 )))

;; get all keys
(require 'subr-x)
(hash-table-keys myHash) ; ("joe" "jane" "liz")

Get All Values

(hash-table-values hash)
Return a list of values. (require 'subr-x) New in emacs 24.4
;; getting all keys from a hash table.

;; creating a hash
(setq myHash (make-hash-table :test 'equal))
(puthash "joe" "19" myHash)
(puthash "jane" "20" myHash)

;; get all keys.
(require 'subr-x)          ; emacs 24.4
(hash-table-values myHash) ; ⇒ ("20" "19")

Hash to List

(defun xah-hash-to-list (HashTable)
  "Return a list that represent the HASHTABLE
Each element is a proper list: '(key value).

URL `http://xahlee.info/emacs/emacs/elisp_hash_table.html'
Version 2019-06-11 2022-05-28"
  (let (($result nil))
    (maphash
     (lambda (k v)
       (push (list k v) $result))
     HashTable)
    $result))

Print Hashtable

(print myHash)

;; sample output
;; #s(hash-table size 65 test equal rehash-size 1.5 rehash-threshold 0.8125 data ("joe" 19 "jane" 16 "carrie" 17 ...))

Here's a pretty print function:

(defun xah-print-hash (hashtable)
  "Prints the hashtable, each line is key, val"
  (maphash
   (lambda (k v)
     (princ (format "%s , %s" k v))
     (princ "\n"))
   hashtable
   ))

;; test

(setq myHash (make-hash-table :test 'equal))
(puthash "joe" 19 myHash)
(puthash "jane" 20 myHash)
(puthash "carrie" 17 myHash)
(puthash "liz" 21 myHash)

(xah-print-hash myHash)

Sort Hash

To sort, first change it to a list.

(setq myHash (make-hash-table :test 'equal))
(puthash "joe" 19 myHash)
(puthash "jane" 20 myHash)
(puthash "carrie" 17 myHash)
(puthash "liz" 21 myHash)

;; get the hash table into a list
(setq myList (xah-hash-to-list myHash))

(setq myList (sort myList (lambda (a b) (string< (car a) (car b)))))

(print myList)

Warning: elisp's sort function is destructive. Once sort is used on a variable, that variable's value is essentially destroyed. (the sorted result is returned.) If you want to keep the variable, make a copy first.

(info "(elisp) Rearrangement")

(info "(elisp) Hash Tables")

Lisp Data Structure

ErgoEmacs mascot-s276x226
Buy Xah Emacs Tutorial

Lisp Basics

Basics

Lisp Data Structure

Function

Lisp Symbol

Lisp Misc

Working with Elisp