Elisp: Hash Table
What is Hash Table
Hash table is a collection of key-value pairs.
Emacs lisp has 2 types of collection of key-value pairs.
- Hash Table → Unordered set of key val pairs. No duplicate keys. Constant access time.
- Association List (aka alist) → A ordered list of key val pairs. Keys may repeat. Slow for random access.
Create Hash Table
make-hash-table-
(make-hash-table :test 'equal)Returns a new hashtable.
Key or Value can be any lisp object (any type). Key type should be the same for all keys.
The
:test 'equalis to specify what test to check key match. 3 possible choices are:'eql(the default.)'eq'equal
🛑 WARNING: you cannot use
string-equal- 🟢 TIP:
- For string keys, use
'equal. - For symbol or integer keys, use
'eq. - For floating number keys, use
'eql.
if you want to use a different test, you have to write one by
define-hash-table-test. See elisp manual.There are more options for
make-hash-table. See elisp manual.;; create a hash table (setq xx (make-hash-table :test 'equal))
🟢 TIP: Don't Use Symbol as Key in Hashtable. Use String.
Best to not use symbol as key in hashtable, because it pollutes the symbol table. Use string instead. Also, if you export to JSON, the key must be string.
Example. Create Hashtable, with String Keys
(progn (setq xx (make-hash-table :test 'equal)) (puthash "a" 1 xx) (puthash "b" 2 xx) (puthash "c" 3 xx) xx) ;; #s(hash-table test equal data ("a" 1 "b" 2 "c" 3)) (gethash "c" xx) ;; 3
Example. Create Hashtable, with Symbol Keys
(progn (setq xx (make-hash-table :test 'eq)) (puthash :a 1 xx) (puthash :b 2 xx) (puthash :c 3 xx) xx) ;; #s(hash-table test eq data (:a 1 :b 2 :c 3)) (gethash :c xx) ;; 3
Example. Create Hashtable, with Integer Keys
(progn (setq xx (make-hash-table :test 'eq)) (puthash 1 30 xx) (puthash 2 71 xx) (puthash 3 49 xx) xx) ;; #s(hash-table test eq data (1 30 2 71 3 49)) (gethash 3 xx) ;; 49
Example. Create Hashtable, with Float Number Keys
(progn (setq xx (make-hash-table :test 'eql)) (puthash 1.067 1 xx) (puthash 2.948 2 xx) (puthash 3.019 3 xx) xx) ;; #s(hash-table data (1.067 1 2.948 2 3.019 3)) (gethash 2.948 xx) ;; 2
Literal Expression for Hashtable
You can create a hash table by a literal expression, like this:
(setq xx #s(hash-table size 30 test equal data ( "aa" 3 "bb" 9 "cc" 5 ))) (gethash "aa" xx ) ;; 3
Length (Count of Entries)
hash-table-count-
(hash-table-count xhash)
Add Entry
puthash-
(puthash KEY VALUE TABLE)(setq xx (make-hash-table :test 'equal)) (puthash "aa" 9 xx) ;; 9
Remove Entry
remhash-
(remhash KEY TABLE)Remove KEY from TABLE.
(setq xx (make-hash-table :test 'equal)) ;; #s(hash-table test equal) (puthash "aa" 9 xx) ;; 9 (puthash "bb" 10 xx) ;; 10 (remhash "aa" xx) ;; nil xx ;; #s(hash-table test equal data ("bb" 10))
Check Key Exist
see gethash
Get Key's Value
gethash-
(gethash key table)(gethash key table default)
If a key exist, return key's value. Else, return
nilor default(let ((xx (make-hash-table :test 'equal))) (puthash "aa" 9 xx) (gethash "aa" xx)) ;; 9 (let ((xx (make-hash-table :test 'equal))) (puthash "aa" 9 xx) (gethash "bb" xx)) ;; nil (let ((xx (make-hash-table :test 'equal))) (puthash "aa" 9 xx) (gethash "bb" xx 10)) ;; 10
Remove All Entries
clrhash-
(clrhash xhash)
Apply a Function to All Entries
maphash-
(maphash f hashtable)Apply a function to all entries in a hash table. The function f must take 2 arguments, key and value.
(setq xx (make-hash-table :test 'equal)) (puthash "aa" 19 xx) (puthash "bb" 20 xx) (puthash "dd" 17 xx) (puthash "cc" 21 xx) (maphash (lambda (k v) (princ (format "%s , %s" k v)) (princ "\n")) xx )
Get All Keys
hash-table-keys-
(hash-table-keys xhash)Return a list of keys.
(require 'subr-x)New in Emacs 24.4 (date 2014-10)
;; get all keys from a hash table (setq xx #s(hash-table size 30 test equal data ( "aa" 3 "bb" 9 "cc" 5 ))) ;; get all keys (require 'subr-x) (hash-table-keys xx) ; ("aa" "bb" "cc")
Get All Values
hash-table-values-
(hash-table-values xhash)Return a list of values.
(require 'subr-x)New in Emacs 24.4 (date 2014-10)
;; getting all keys from a hash table. ;; hash table (setq xx (make-hash-table :test 'equal)) (puthash "aa" "19" xx) (puthash "bb" "20" xx) ;; get all keys. (require 'subr-x) ; emacs 24.4 (hash-table-values xx) ; ("20" "19")