9

我正在寻找一种可能不冗长的可移植方式来初始化 Common Lisp 中的哈希表。例如,适用于常量哈希表的东西,也适用于预加载变量哈希。在 CLISP 中,我正在使用:

(defconstant +my-map+ #S(HASH-TABLE :TEST FASTHASH-EQ
  (key1 . "value1")
  ...
  (keyN . "valueN")
))

但不幸的是,这种格式只适用于 CLISP。

4

4 回答 4

9

可以在读取时以编程方式构造哈希表:

(defvar *ht* #.(let ((ht (make-hash-table)))
                 (loop for (key . value) in
                       '((a . 1) (b . 2) (c . 3))
                       do (setf (gethash key ht) value))
                 ht))

(describe *ht*)

#.用于读取时间评估。然后编译器会将哈希表转储到 FASL 文件中。

然后可以编译:

使用 SBCL:

* (compile-file "/tmp/test.lisp")

; compiling file "/private/tmp/test.lisp" (written 24 MAY 2012 10:08:49 PM):
; compiling (DEFVAR *HT* ...)
; compiling (DESCRIBE *HT*)

; /tmp/test.fasl written
; compilation finished in 0:00:00.360
#P"/private/tmp/test.fasl"
NIL
NIL
* (load *)

#<HASH-TABLE :TEST EQL :COUNT 3 {100299EA43}>
  [hash-table]

Occupancy: 0.2
Rehash-threshold: 1.0
Rehash-size: 1.5
Size: 16
Synchronized: no
T
* *ht*

#<HASH-TABLE :TEST EQL :COUNT 3 {100299EA43}>

将哈希表创建为函数:

(defun create-hashtable (alist
                         &key (test 'eql)
                         &aux (ht (make-hash-table :test test)))
  (loop for (key . value) in alist
        do (setf (gethash key ht) value))
  ht)
于 2012-05-24T20:24:27.277 回答
2

Alexandria具有该alist-hash-table功能,您可能会发现它很有用。

于 2012-05-23T05:41:55.793 回答
0

Serapeum图书馆有dict

(dict :a 1 :b 2 :c 3)
#<HASH-TABLE :TEST EQUAL :COUNT 3 {1008906D13}>

您可以漂亮地打印哈希表:

CL-USER> (toggle-pretty-print-hash-table)
T
CL-USER> (dict :a 1 :b 2 :c 3)
(dict
  :A 1
  :B 2
  :C 3
 ) 

这是可以读回的表示。

我们也可以pretty-print-hash-table直接使用。

Serapeum 是一个高质量的图书馆。

ps:我的CIEL元包dict默认是可用的。

于 2021-09-02T09:49:23.197 回答
0

哇,9年前的一个问题得到了另一个答案。巧合的是,在提出这个问题 2 个月后, make-hash出现了,并且通常对这类事情有用。

于 2021-09-03T13:15:30.143 回答