Convert nested hash-tables to a-list how to ensure the creation dotted pairs

62 Views Asked by At

I wrote the following function to convert nested hash-tables to an a-list:

(defun hash-table->alist* (ht)
  (loop for k being the hash-keys in ht using (hash-value v)
        collect (cons k
                      (etypecase v
                        (integer v)
                        (hash-table (hash-table->alist* v))))))

It works fine for non nested hash-tables:

> (hash-table->alist* (dict :a 1 :b 23 :c 4))
((:A . 1) (:B . 23) (:C . 4))

But when I use it on nested hash-tables I loose the dotted-pairs on the way:

> (hash-table->alist* (dict :session (dict :user (dict :fullname 23))))
((:SESSION (:USER (:FULLNAME . 23))))

How can I ensure the creation of a dotted pair instead of appending to the front of a list?

1

There are 1 best solutions below

0
Svante On BEST ANSWER

I guess you expected:

((:SESSION . ((:USER . ((:FULLNAME . 23))))))

However, if the cdr of a cons cell contains a list, this implies a list structure, which is printed without dot and without nested parentheses. This is how lists are defined: (A . (B)) is (A B). So, this is exactly the same structure:

((:SESSION (:USER (:FULLNAME . 23))))

This confusion is unavoidable, because the fact that a given list structure is meant as an alist is not possible to discern from the structure itself.