Hi all,
I was wondering what's the right way to copy an array in
Lisp. For example, something like:
2. Break> (setf a1 (make-array '(2 2) :initial-element 1))
#2A((1 1) (1 1))
2. Break> (setf a2 a1)
#2A((1 1) (1 1))
2. Break> (setf (aref a2 0 0) 0)
0
2. Break> a2
#2A((0 1) (1 1))
2. Break> a1
#2A((0 1) (1 1))
^^^
also alters a1 which is not what I want. One possible way that I see
is to call make-array and then copy element by element, but this
sounds like Basic to me.
Thanx in advance,
--
Dragos Manolescu WILL AM/FM/TV
1110 W. Main Street
e-mail: ········@uiuc.edu Urbana, IL 61801
Phone: (217)333-1070
In article <··············@sweetbay.will.uiuc.edu>,
Dragos-Anton Manolescu <········@uiuc.edu> wrote:
>2. Break> (setf a1 (make-array '(2 2) :initial-element 1))
>#2A((1 1) (1 1))
>2. Break> (setf a2 a1)
>#2A((1 1) (1 1))
>2. Break> (setf (aref a2 0 0) 0)
>0
>2. Break> a2
>#2A((0 1) (1 1))
>2. Break> a1
>#2A((0 1) (1 1))
> ^^^
>
>also alters a1 which is not what I want.
Of course you understand that A1 and A2 are variables which refer to the
*same* array. Lisp is based on objects with identity independent of the
variables used to refer to them.
> One possible way that I see
>is to call make-array and then copy element by element, but this
>sounds like Basic to me.
Unfortunately, Common Lisp doesn't have a standard function for copying an
array. There was a proposal once in X3J13 to extend some of the sequence
functions to work on multi-dimensional arrays, but it was not adopted. It
also seems to me that it would make sense to allow another array of the
same dimensions as the :INITIAL-ELEMENTS argument to MAKE-ARRAY, but this
doesn't work.
For one-dimensional arrays (vectors) you can use COPY-SEQ.
It's pretty easy to write a function that calls MAKE-ARRAY and then copies
element by element using ROW-MAJOR-AREF:
(setq new-array (make-array (array-dimensions old-array)
:element-type (array-element-type old-array)))
(dotimes (i (array-total-size old-array))
(setf (row-major-aref new-array i) (row-major-aref old-array i)))
--
Barry Margolin
BBN PlaNET Corporation, Cambridge, MA
······@bbnplanet.com
Phone (617) 873-3126 - Fax (617) 873-6351
Hello,
······@tools.bbnplanet.com (Barry Margolin) wrote:
>In article <··············@sweetbay.will.uiuc.edu>,
>Dragos-Anton Manolescu <········@uiuc.edu> wrote:
>>2. Break> (setf a1 (make-array '(2 2) :initial-element 1))
...
>Unfortunately, Common Lisp doesn't have a standard function for copying an
>array. There was a proposal once in X3J13 to extend some of the sequence
>functions to work on multi-dimensional arrays, but it was not adopted. It
>also seems to me that it would make sense to allow another array of the
>same dimensions as the :INITIAL-ELEMENTS argument to MAKE-ARRAY, but this
>doesn't work.
...
Here is the copy array function I use:
#+example
(let* ((array (make-array '(2 2) :initial-element (list 0 1)))
(array-1 (copy-array-2 array))
(array-2 (copy-array-2 array :key #'first)))
(setf (aref array-1 0 0) 0)
(print array)
(print array-1)
(print array-2)
(values))
(defun copy-array-2 (from-array &key to-array key)
(unless to-array
(setf to-array (make-array (array-dimensions from-array)
:element-type (array-element-type from-array)
:adjustable (adjustable-array-p from-array)
:fill-pointer (and (array-has-fill-pointer-p
from-array)
(fill-pointer from-array)))))
(dotimes (i (array-total-size from-array))
(setf (row-major-aref to-array i)
(if key
(funcall key (row-major-aref from-array i))
(row-major-aref from-array i))))
to-array)
Francis Leboutte
Algorithme
Rue de la Charrette, 141 - 4130 Tilff - Belgium
T&FAX: 32-(0)41-883528
Internet: ········@mail.interpac.be
········@tractebel.be