我正在使用过程
hash-set
在 hash?
中设置值。似乎要求哈希值是immutable?
。到目前为止,我找不到比以下更好的方法将可变哈希转换为不可变哈希:
(make-immutable-hash(哈希->列出 myhash))
哈希值是一些
yaml
,我正在从文件中读取它,并且 yaml
模块为我提供了一个可变哈希值。例如我有以下代码:
(hash-set yaml-hash
"content"
(make-immutable-hash
(hash->list
(my-hash-map content-hash
(lambda (key value)
(cons key
(markdown-to-html value)))))))
是否有更好的方法将可变哈希转换为不可变哈希,以便更新它?还是我应该走不同的路?
如果哈希值一开始就是可变的,你可以直接使用
hash-set!
: 修改它
(hash-set! yaml-hash <key> <new-value>)
上面的内容将就地更改哈希值,而
hash-set
将返回一个new哈希值,您必须将其存储或重新分配到其他地方。
我找不到比以下更好的方法将可变哈希转换为不可变哈希:
(make-immutable-hash (hash->list myhash))
for/hash
理解 和 in-hash
序列 一次迭代一个可变哈希的条目,而不是首先构建所有条目的列表:
;;; Contract: (-> hash? (and/c hash? immutable?))
(define (hash->immutable-hash table)
(if (immutable? table)
table ;; If hash is already immutable, just return it
(for/hash ([(k v) (in-mutable-hash my-table)]) (values k v))))
Racket 8.6 在我最初发布此答案后不久发布,添加了一个
hash-map/copy
函数,该函数也可用于制作可变哈希的不可变副本。与上面不同的是,它保留了表的相等函数(eq?
、eqv?
、equal?
、equal-always?
)。
使用它的上述版本,这是现在我的首选方法:
;;; Contract: (-> hash? (and/c hash? immutable?))
(define (hash->immutable-hash table)
(if (immutable? table)
table ;; If hash is already immutable, just return it
(hash-map/copy table values #:kind 'immutable)))