Lisp beginner here.
I have two string lists in this form with same length:
keys = ("abc" "def" "gh" ...)
values = ("qwe" "opr" "kmn" ...)
I need to construct hash-table or association lists (whichever is easy to construct and fast to get values from) from those lists. They are in the proper index due to their pair.
I know I can map them with iterating. But I want go with a more declarative way and I am looking for a clean way to this, if it can be done so.
There is a dedicated function named PAIRLIS
that does exactly what what you want to build association lists:
USER> (pairlis '("abc" "def" "gh")
'("qwe" "opr" "kmn"))
(("gh" . "kmn") ("def" . "opr") ("abc" . "qwe"))
Note that the order is reversed, but this depends on the implementation. Here orders does not matter since your keys are unique.
Then, you can use the popular alexandria library to build a hash-table from that:
USER> (alexandria:alist-hash-table * :test #'equalp)
#<HASH-TABLE :TEST EQUALP :COUNT 3 {101C66ECA3}>
Here I am using a hash-table with test equalp
because your keys are strings.
NB. The *
symbol refers to the last primary value in a REPL
You could do something such as mapcar which will handle the iteration for you, vs. manually entering some sort of loop for iteration. For example:
(defvar *first-names* '("tom" "aaron" "drew"))
(defvar *last-names* '("brady" "rogers" "brees"))
(defvar *names-table* (make-hash-table))
We could create a list of the two sets of names and then a hashtable (or alist if you prefer). Then we can simply user mapcar to map through the list of us instead of manually entering a loop such as do, dolist, dotimes, loop ect…
(mapcar #'(lambda (first last)
(setf (gethash first *names-table*) last))
*first-names*
*last-names*)
mapping is particularly useful for lists in common lisp.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With