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

Get Key's Value

(gethash "jane" myHash)

Number of Entries

(hash-table-count myHash)

Remove All Entries

(clrhash myHash)

Check Key Exist

(gethash key table)
Check if a key exist. If so, return the 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
  )

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 (@hash-table)
  "Return a list that represent the @HASH-TABLE
Each element is a list: '(key value).

http://ergoemacs.org/emacs/elisp_hash_table.html
Version 2019-06-11"
  (let ($result)
    (maphash
     (lambda (k v)
       (push (list k v) $result))
     @hash-table)
    $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 my-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)

(my-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")

Put $5 at https://www.patreon.com/xahlee , or goto paypal.com and pay to Xah@XahLee.org . Message me on XahLee discord, say so, ask me questions.
Or Buy Xah Emacs Tutorial

Emacs Tutorial

Emacs Init

Emacs Keys

ELisp

ELisp Examples

ELisp Write Major Mode


ELisp

Basics

Basic Functions

Writing Command

Writing Script

Lisp Data Structure

Lisp Symbol

Elisp Misc