Hash Tables
Options: :size, :rehash-size, and (SBCL) :synchronized t for thread-safe tables or :weakness :key for weak tables.
(defparameter *phone* (make-hash-table :test 'equal)) ; tests: eq, eql (default), equal, equalp
(setf (gethash "ana" *phone*) "555-1234")
(setf (gethash "bo" *phone*) "555-9876")
(gethash "ana" *phone*) ; "555-1234", T (value and found-p)
(gethash "zed" *phone*) ; NIL, NIL
(gethash "zed" *phone* "unknown") ; "unknown", NIL (default)
(remhash "bo" *phone*)
(hash-table-count *phone*) ; 1
(clrhash *phone*)
(maphash (lambda (k v) (format t "~a => ~a~%" k v)) *phone*)
(loop for k being the hash-keys of *phone* using (hash-value v)
collect (cons k v))
(with-hash-table-iterator (next *phone*)
(loop (multiple-value-bind (more k v) (next)
(unless more (return))
(print (list k v)))))
;; Counting with incf on gethash (missing keys start at the default 0)
(defun word-counts (words)
(let ((counts (make-hash-table :test 'equal)))
(dolist (w words counts)
(incf (gethash w counts 0)))))
(alexandria:hash-table-alist (word-counts '("a" "b" "a"))) ; (("b" . 1) ("a" . 2)) (order unspecified)
;; Distinguishing "stored NIL" from "missing"
(multiple-value-bind (value found) (gethash :key (make-ha
…