aboutsummaryrefslogtreecommitdiff
path: root/src/hash-table.lisp
blob: a53eb72a7dd3d2088be2488c85941b08926a5693 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
(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))))