Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mapping two string lists (in a short way) in Lisp?

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.

like image 552
drh0use Avatar asked Dec 31 '22 11:12

drh0use


2 Answers

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

like image 77
coredump Avatar answered Jan 06 '23 10:01

coredump


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.

like image 21
Simeon Ikudabo Avatar answered Jan 06 '23 09:01

Simeon Ikudabo