在Lisp中复制哈希表

时间:2014-09-25 18:19:39

标签: copy hashtable common-lisp

我最近一直在使用Common Lisp中的哈希表。我一直在想如何制作一个包含与第一个相同的值的哈希表的单独副本。有正式的方法吗?如果没有,你能用maphash给我一个例子吗?

3 个答案:

答案 0 :(得分:5)

由于clhs没有列出复制表功能,我认为maphash是要走的路。

(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}>

然而,此函数不考虑哈希表的特殊配置,但它应该足够作为一个例子。

答案 1 :(得分:5)

Sim's answer复制一个哈希表,但哈希表有两个其他功能,可能很好地复制表的有效填充。这是一个保留该信息的版本,还展示了循环使用哈希表的能力(作为 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))))

答案 2 :(得分:2)

请勿重新发明轮子,请使用Alexandria中的copy-hash-table