Skip to main content

maphash

maphash Function

Syntax:

maphash function hash-table → nil

Arguments and Values:

function—a designator for a function of two arguments, the key and the value.

hash-table—a hash table.

Description:

Iterates over all entries in the hash-table. For each entry, the function is called with two arguments–the key and the value of that entry.

The consequences are unspecified if any attempt is made to add or remove an entry from the hash-table while a maphash is in progress, with two exceptions: the function can use can use setf of gethash to change the value part of the entry currently being processed, or it can use remhash to remove that entry.

Examples:

(setq table (make-hash-table)) → #<HASH-TABLE EQL 0/120 32304110> 
(dotimes (i 10) (setf (gethash i table) i)) → NIL
(let ((sum-of-squares 0))
(maphash #’(lambda (key val)
(let ((square (\* val val)))
(incf sum-of-squares square)
(setf (gethash key table) square)))
table)
sum-of-squares)285
(hash-table-count table)10
(maphash #’(lambda (key val)
(when (oddp val) (remhash key table)))
table) → NIL
(hash-table-count table)5
(maphash #’(lambda (k v) (print (list k v))) table)
(0 0)
(8 64)
(2 4)
(6 36)
(4 16)
→ NIL

Side Effects:

None, other than any which might be done by the function.

See Also:

loop, with-hash-table-iterator, Section 3.6 (Traversal Rules and Side Effects)

Expanded Reference: maphash

Basic Iteration

maphash calls a two-argument function on every key-value pair in a hash table and returns nil.

(let ((ht (make-hash-table)))
(setf (gethash 'a ht) 1)
(setf (gethash 'b ht) 2)
(setf (gethash 'c ht) 3)
(maphash (lambda (key value)
(format t "~A => ~A~%" key value))
ht))
;; Prints (order may vary):
;; A => 1
;; B => 2
;; C => 3
;; => NIL

Collecting Entries into a List

(let ((ht (make-hash-table :test #'equal)))
(setf (gethash "x" ht) 10)
(setf (gethash "y" ht) 20)
(setf (gethash "z" ht) 30)
(let ((pairs '()))
(maphash (lambda (k v) (push (cons k v) pairs)) ht)
;; Sort for deterministic output
(sort pairs #'string< :key #'car)))
=> (("x" . 10) ("y" . 20) ("z" . 30))

Modifying Values During Iteration

Within maphash, you may use setf of gethash to change the current entry's value.

;; Square all values in the hash table
(let ((ht (make-hash-table)))
(dotimes (i 5) (setf (gethash i ht) (1+ i)))
(maphash (lambda (key value)
(setf (gethash key ht) (* value value)))
ht)
(list (gethash 0 ht) (gethash 1 ht) (gethash 2 ht)
(gethash 3 ht) (gethash 4 ht)))
=> (1 4 9 16 25)

Removing Entries During Iteration

You may call remhash on the current entry during maphash.

;; Remove all entries where the value is less than 3
(let ((ht (make-hash-table)))
(setf (gethash 'a ht) 1)
(setf (gethash 'b ht) 5)
(setf (gethash 'c ht) 2)
(setf (gethash 'd ht) 4)
(maphash (lambda (key value)
(when (< value 3) (remhash key ht)))
ht)
(hash-table-count ht))
=> 2

Summing Values

(let ((ht (make-hash-table)))
(setf (gethash 'apples ht) 3)
(setf (gethash 'bananas ht) 7)
(setf (gethash 'cherries ht) 15)
(let ((total 0))
(maphash (lambda (key value)
(declare (ignore key))
(incf total value))
ht)
total))
=> 25