在Lisp中映射两个字符串列表(以简短方式)?

Lisp初学者在这里。

我有两个这种长度相同的字符串列表:

  keys = ("abc" "def" "gh" ...)
  values = ("qwe" "opr" "kmn" ...)

我需要从这些列表构造哈希表或关联列表(无论是哪种构造方法都很容易并且可以从中快速获取值)。由于配对,它们处于适当的索引中。

我知道我可以通过迭代来映射它们。但是我想采用一种更具声明性的方式,如果可以的话,我正在寻找一种干净的方式。

fd1803 回答:在Lisp中映射两个字符串列表(以简短方式)?

有一个名为PAIRLIS的专用函数,它可以完成您想要建立的关联列表:

USER> (pairlis '("abc" "def" "gh")
               '("qwe" "opr" "kmn"))
(("gh" . "kmn") ("def" . "opr") ("abc" . "qwe"))

请注意,顺序是相反的,但这取决于实现方式。因为您的键是唯一的,所以这里的顺序无关紧要。

然后,您可以使用流行的alexandria库从该库构建哈希表:

USER> (alexandria:alist-hash-table * :test #'equalp)
#<HASH-TABLE :TEST EQUALP :COUNT 3 {101C66ECA3}>

在这里,我将哈希表与测试equalp一起使用,因为您的密钥是字符串。

NB。 *符号指的是REPL中的最后一个主值

,

您可以执行诸如mapcar之类的操作来为您处理迭代,而不是手动输入某种循环进行迭代。例如:

(defvar *first-names* '("tom" "aaron" "drew"))
(defvar *last-names* '("brady" "rogers" "brees"))
(defvar *names-table* (make-hash-table))

我们可以创建一个包含两组名称的列表,然后创建一个哈希表(如果需要,可以创建一个列表)。然后,我们可以简单地使用mapcar来映射我们的列表,而不用手动输入诸如do,dolist,dotimes,loop ect之类的循环……

(mapcar #'(lambda (first last)
           (setf (gethash first *names-table*) last))
       *first-names*
       *last-names*)

映射对于常见Lisp中的列表特别有用。

,

请注意,除了pairlis和c以外,诸如mapcar之类的常规映射函数实际上也接受多个列表参数,并调用在每个参数上映射的函数。因此,pairlis的(一部分)思想简单的版本可能是:

(defun kv->alist (keys values)
  (mapcar #'cons keys values))

(实际上,在某些情况下,它比pairlis更具优势:确定结果的顺序。)

如果要创建哈希表:

(defun kv->ht (keys values &key (test #'eql))
  (let ((ht (make-hash-table :test test)))
    (mapc (lambda (k v)
            (setf (gethash k ht) v))
          keys values)
    ht))
本文链接:https://www.f2er.com/3056775.html

大家都在问