Copy Hash Table in Lisp

2019-04-30 20:31发布

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?

3条回答
Melony?
2楼-- · 2019-04-30 20:43

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.

查看更多
狗以群分
3楼-- · 2019-04-30 20:59

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))))
查看更多
一夜七次
4楼-- · 2019-04-30 21:05

Don't reinvent the wheel, use copy-hash-table from Alexandria.

查看更多
登录 后发表回答