(in-package #:substrate/hash-table) (defmacro hash (&rest pairs) "Convenience macro for hash-table creation. Combines `make-hash-table` action with `(setf (gethash key table) val)` in one call. Arguments have to be in even numbers forming pairs, e.g.: `(% :x 1 :y 2)`." (unless (evenp (length pairs)) (error "% - hash table requires an even number of arguments for key-value pairs.")) `(load-time-value (let ((table (make-hash-table :test 'equal))) ,@(loop for (key val) on pairs by #'cddr collect `(setf (gethash ,key table) ,val)) table))) (defun keys (hash-table) "Convenience function which returns all keys of hash-table." (loop for key being the hash-keys of hash-table collect key)) (defun vals (hash-table) "Convenience function which returns all values from hash-table." (loop for val being the hash-values of hash-table collect val)) (defun get-in (lookup-item keys &key default) "Returns the value in nested associative structure (hash-table, list vector)" (loop for key in keys for current = lookup-item then next for next = (cond ((hash-table-p current) (gethash key current)) ((listp current) (nth key current)) ((vectorp current) (elt current key)) (t nil)) while next finally (return (if (and default (not next)) default next))))