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?
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.
Sim's answer copies a hash table, but there are two other features of hash tables thst 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))))
Don't reinvent the wheel, use copy-hash-table
from Alexandria.
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.
© 2022 - 2024 — McMap. All rights reserved.