I'm trying to find out a way to create a copy of an array with switched rows and columns.
I want to do this by setting pointers from the shadow array to the original array so that item[2 1] points to item[1 2].
Using pointers will have the effect that when the original array is changed, the shadowed array will also reflect that change.
So far I came up with using displaced arrays of length 1 for every item in the array.
It works but the result is an array with array's.
My question is, is there a better way to do this?
And is there a way to use setf through the shadow array to set values in the original array?
My code so far:
(defun shadow-column-array (array)
(let* ((colsize (second (array-dimensions array)))
(rowsize (first (array-dimensions array)))
(b (make-array (list colsize rowsize))))
(dotimes (i rowsize b)
(dotimes (j colsize)
(setf (aref b j i)
(make-array 1
:displaced-to array
:displaced-index-offset (+ (* i rowsize) j)))))))
some output:
*a* => #2A((0.0 0.1 0.2) (1.0 1.1 1.2) (2.0 2.1 2.2))
(setq b (shadow-column-array (*a*))
*b* => #2A((#(0.0) #(1.0) #(2.0)) (#(0.1) #(1.1) #(2.1)) (#(0.2) #(1.2) #(2.2)))
displaced arrays of the columns are now
col1 => #(#(0.0) #(1.0) #(2.0))
col2 => #(#(0.1) #(1.1) #(2.1))
col3 => #(#(0.2) #(1.2) #(2.2))
I would maybe use two arrays and set both when I change the contents. You can write a SETF function for that easily. If it should look like a single data structure for the user, I would also use a CLOS instance with slots for the array.