copy-alist
copy-alist Function
Syntax:
copy-alist alist → new-alist
Arguments and Values:
alist—an association list.
new-alist—an association list.
Description:
copy-alist returns a copy of alist.
The list structure of alist is copied, and the elements of alist which are conses are also copied (as conses only). Any other objects which are referred to, whether directly or indirectly, by the alist continue to be shared.
Examples:
(defparameter \*alist\* (acons 1 "one" (acons 2 "two" ’())))
\*alist\* → ((1 . "one") (2 . "two"))
(defparameter \*list-copy\* (copy-list \*alist\*))
\*list-copy\* → ((1 . "one") (2 . "two"))
(defparameter \*alist-copy\* (copy-alist \*alist\*))
\*alist-copy\* → ((1 . "one") (2 . "two"))
(setf (cdr (assoc 2 \*alist-copy\*)) "deux") → "deux"
\*alist-copy\* → ((1 . "one") (2 . "deux"))
\*alist\* → ((1 . "one") (2 . "two"))
(setf (cdr (assoc 1 \*list-copy\*)) "uno") → "uno"
\*list-copy\* → ((1 . "uno") (2 . "two"))
\*alist\* → ((1 . "uno") (2 . "two"))
See Also:
copy-listExpanded Reference: copy-alist
Basic usage
copy-alist creates a copy of an association list, making fresh copies of both the top-level spine and each cons pair (the key-value pairs).
(let ((original '((a . 1) (b . 2) (c . 3))))
(copy-alist original))
=> ((A . 1) (B . 2) (C . 3))
Modifying the copy does not affect the original
Because copy-alist copies each cons pair, modifying a value in the copy does not change the original alist.
(let* ((original '((a . 1) (b . 2)))
(copied (copy-alist original)))
(setf (cdr (assoc 'a copied)) 99)
(values original copied))
=> ((A . 1) (B . 2))
=> ((A . 99) (B . 2))
Difference from copy-list
copy-list only copies the spine (top-level conses) but shares the cons pairs. Modifying a pair through a copy-list result also modifies the original.
(let* ((original (list (cons 'x 10) (cons 'y 20)))
(list-copy (copy-list original))
(alist-copy (copy-alist original)))
;; Modifying through list-copy affects original
(setf (cdr (assoc 'x list-copy)) 999)
;; Modifying through alist-copy does NOT affect original
(setf (cdr (assoc 'y alist-copy)) 888)
(values original list-copy alist-copy))
=> ((X . 999) (Y . 20))
=> ((X . 999) (Y . 20))
=> ((X . 10) (Y . 888))
Shared values are still shared
While the cons pairs are copied, the actual key and value objects are still shared (not deeply copied).
(let* ((shared-value (list 1 2 3))
(original (list (cons 'data shared-value)))
(copied (copy-alist original)))
(eq (cdr (first original))
(cdr (first copied))))
=> T