The keys and values of a hash table can be iterated over using the macro with-hash-table-iterator. This may be a bit more complex than maphash or loop, but it could be used to implement the iteration constructs used in those methods. with-hash-table-iterator takes a name and a hash table and binds the name within a body such that successive calls to the name produce multiple values: (i) a boolean indicating whether a value is present; (ii) the key of the entry; and (iii) the value of the entry.
(let ((ht (make-hash-table)))
(setf (gethash 'a ht) 1
(gethash 'b ht) 2)
(with-hash-table-iterator (iterator ht)
(print (multiple-value-list (iterator)))
(print (multiple-value-list (iterator)))
(print (multiple-value-list (iterator)))))
;; (T A 1)
;; (T B 2)
;; (NIL)