2014-09-25 57 views
4

我最近一直在Common Lisp中使用哈希表。我一直想知道如何製作一個包含與第一個相同的值的哈希表的單獨副本。有沒有官方的方式來做到這一點?如果沒有,你可以給我一個使用maphash的例子嗎?在Lisp中複製哈希表

+1

我想你可能也有興趣在[不可變的散列表](http://common-lisp.net/projects/fset/Site/index.html)。如果你複製很多,它可能會更有效。 – Sylwester 2014-09-25 22:01:47

+1

廣泛使用的亞歷山大圖書館有一個副本哈希表函數 – mcheema 2017-01-03 20:43:41

回答

4

由於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}> 

此功能但是不走哈希表的特殊配置考慮在內,但應足以作爲一個例子。

+0

謝謝,這樣做,我編程康威的生活遊戲,我只需要創建一個臨時副本,我可以修改爲下一代而不影響當代。現在效果很好。 – thelostlambda 2014-09-26 15:45:49

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

不要重新發明輪子,用copy-hash-tableAlexandria