I have recently been working with hash tables in Common Lisp. I have been wondering how to make a separate copy of a hash table containing all the same values as the first. Is there an official way to do this? If not, can you give me an example using maphash?
可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
回答1:
As clhs does not list a copy table function I'd assume that maphash is the way to go.
(defun copy-table (table)
(let ((new-table (make-hash-table
:test (hash-table-test table)
:size (hash-table-size table))))
(maphash #'(lambda(key value)
(setf (gethash key new-table) value))
table)
new-table))
(let ((table (make-hash-table)))
(mapcar #'(lambda(arg argg)
(setf (gethash arg table) argg))
'(1 2 3 4) '(a b c d))
(format t "~a~%" table)
(format t "~a~%" (copy-table table)))
#<HASH-TABLE :TEST EQL :COUNT 4 {10063C7F13}>
#<HASH-TABLE :TEST EQL :COUNT 4 {10063C86D3}>
This function however does not take special configurations of the hashtable into account, but it should suffice as an example.
回答2:
Sim's answer copies a hash table, but there are two other features of hash tables taht might be good to copy for efficient population of the table. Here's a version that preserves that information, and also showcases loop's ability to work with hash tables (as an alternative to maphash):
(defun copy-hash-table (hash-table)
(let ((ht (make-hash-table
:test (hash-table-test hash-table)
:rehash-size (hash-table-rehash-size hash-table)
:rehash-threshold (hash-table-rehash-threshold hash-table)
:size (hash-table-size hash-table))))
(loop for key being each hash-key of hash-table
using (hash-value value)
do (setf (gethash key ht) value)
finally (return ht))))
回答3:
Don't reinvent the wheel, use copy-hash-table
from Alexandria.