Access a specific row from an array

Discussion of Common Lisp
Post Reply
Ferreira
Posts: 5
Joined: Thu Apr 02, 2009 5:07 am

Access a specific row from an array

Post by Ferreira » Wed Apr 22, 2009 11:27 am

Is there any way I can access a specific row from an array, i.e., I have this array:

#2A((1 2) (3 4))

How can I get the first row as #A(1 2)?

Thanks in advance.

gugamilare
Posts: 406
Joined: Sat Mar 07, 2009 6:17 pm
Location: Brazil
Contact:

Re: Access a specific row from an array

Post by gugamilare » Wed Apr 22, 2009 12:35 pm

Unfortunately, I believe the only way to do this explicitly is to create a fresh vector and copy over the elements of that row. You can also do this implictly using closures:

Code: Select all

(defun nth-row (array index)
  (lambda (col)
    (aref array index col)))
And

Code: Select all

(let* ((array #2A((1 2) (3 4)))
       (row-0 (nth-row array 0)))
  (dotimes (i 2)
    (print (funcall row-0 i))))
And, if you want to be able to change the value

Code: Select all

(defun nth-row (array index)
  (lambda (col &optional new-val)
    (if new-val
      (setf (aref array index col) new-val)
      (aref array index col))))

ramarren
Posts: 613
Joined: Sun Jun 29, 2008 4:02 am
Location: Warsaw, Poland
Contact:

Re: Access a specific row from an array

Post by ramarren » Wed Apr 22, 2009 1:07 pm

See documentation on make-array, in particular :displaced-to and :displaced-index-offset, for example:

Code: Select all

CL-USER> (defparameter *a* (make-array (list 2 2) :initial-contents '((1 2)(3 4))))
*A*
CL-USER> (make-array 2 :displaced-to *a*)
#(1 2)
CL-USER> (make-array 2 :displaced-to *a* :displaced-index-offset 1)
#(2 3)
CL-USER> (make-array 2 :displaced-to *a* :displaced-index-offset 2)
#(3 4)
Note that due to how arrays are laid out in memory this can only be used to access rows or parts of rows, and not columns.

There is also affine indexing library, which might be used for similar purposes.

Ferreira
Posts: 5
Joined: Thu Apr 02, 2009 5:07 am

Re: Access a specific row from an array

Post by Ferreira » Wed Apr 22, 2009 1:21 pm

Thanks, make-array's keyworded parameters solved my problem.

;)

gugamilare
Posts: 406
Joined: Sat Mar 07, 2009 6:17 pm
Location: Brazil
Contact:

Re: Access a specific row from an array

Post by gugamilare » Wed Apr 22, 2009 2:07 pm

Ramarren wrote:See documentation on make-array, in particular :displaced-to and :displaced-index-offset, for example:

Code: Select all

CL-USER> (defparameter *a* (make-array (list 2 2) :initial-contents '((1 2)(3 4))))
*A*
CL-USER> (make-array 2 :displaced-to *a*)
#(1 2)
CL-USER> (make-array 2 :displaced-to *a* :displaced-index-offset 1)
#(2 3)
CL-USER> (make-array 2 :displaced-to *a* :displaced-index-offset 2)
#(3 4)
Note that due to how arrays are laid out in memory this can only be used to access rows or parts of rows, and not columns.

There is also affine indexing library, which might be used for similar purposes.
Hum, my bad, I didn't think about this. Oftenly I use displaced arrays to turn multidimentional arrays into one-dimensional, or to make a destructive version of subseq.

But this doesn't work with columns, and my version can be easily addapted :)

Post Reply