Access a specific row from an array

Discussion of Common Lisp

Access a specific row from an array

Postby 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.
Ferreira
 
Posts: 5
Joined: Thu Apr 02, 2009 5:07 am

Re: Access a specific row from an array

Postby 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))))
gugamilare
 
Posts: 406
Joined: Sat Mar 07, 2009 6:17 pm
Location: Brazil

Re: Access a specific row from an array

Postby 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.
Ramarren
 
Posts: 613
Joined: Sun Jun 29, 2008 4:02 am
Location: Warsaw, Poland

Re: Access a specific row from an array

Postby Ferreira » Wed Apr 22, 2009 1:21 pm

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

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

Re: Access a specific row from an array

Postby 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 :)
gugamilare
 
Posts: 406
Joined: Sat Mar 07, 2009 6:17 pm
Location: Brazil


Return to Common Lisp

Who is online

Users browsing this forum: Yahoo [Bot] and 6 guests

cron