A hash map associates keys with values and promises to find all values in more or less equal time (unlike an alist, where stuff at the front is found faster than stuff at the back).
See the Elisp manual, node Hash Tables.
For a more consistent and extensive interface to hash tables, see the library ht - https://github.com/Wilfred/ht.el.
‘equal’
is the same as ‘eq’
for hash tables, to check if two hash tables define the same set of key ⇒ value mappings, use:
(defconst hash-table-equal--sentinel (make-symbol "hash-table-equal--sentinel")) (defun hash-table-equal-p (h1 h2) "Return non-nil if hash-table H1 has same keys & values as H2." (and (= (hash-table-count h1) (hash-table-count h2)) (catch 'equal (maphash (lambda (k v) (unless (equal v (gethash k h2 hash-table-equal--sentinel)) (throw 'equal nil))) h2) t)))
The ht library mentioned above provides a similar ‘ht-equal-p’
predicate.
The big part here is getting the interactive declaration right so that completion will only show you variables that contain in fact hash maps as values, and so that it will show the variable at point if possible.
(defun describe-hash (variable &optional buffer) "Display the full documentation of VARIABLE (a symbol). Returns the documentation as a string, also. If VARIABLE has a buffer-local value in BUFFER (default to the current buffer), it is displayed along with the global value." (interactive (let ((v (variable-at-point)) (enable-recursive-minibuffers t) val) (setq val (completing-read (if (and (symbolp v) (hash-table-p (symbol-value v))) (format "Describe hash-map (default %s): " v) "Describe hash-map: ") obarray (lambda (atom) (and (boundp atom) (hash-table-p (symbol-value atom)))) t nil nil (if (hash-table-p v) (symbol-name v)))) (list (if (equal val "") v (intern val))))) (with-output-to-temp-buffer (help-buffer) (maphash (lambda (key value) (pp key) (princ " => ") (pp value) (terpri)) (symbol-value variable))))
I use describe-hash all the time. Its great unless except for when you have nested hash-tables. For that I use a slightly modified version:
(with-output-to-temp-buffer (help-buffer)
(describe-hash-descend (symbol-value variable))))
(defun describe-hash-descend (hash) "Recursive describe hash func for nested hash-tables" (maphash (lambda (key value) (pp key) (princ " => ") (if (hash-table-p value) (progn (princ " { ") (terpri) (describe-hash-descend value) (princ " } ")) (pp value)) (terpri)) hash))