Path: g2news1.google.com!news3.google.com!fu-berlin.de!uni-berlin.de!individual.net!not-for-mail From: Tamas K Papp Newsgroups: comp.lang.lisp Subject: Re: adjustable arrays Date: 29 Apr 2010 15:45:19 GMT Lines: 54 Message-ID: <83tnsfFuv2U1@mid.individual.net> References: <4bd995fd$0$9895$80265adb@spool.cs.wisc.edu> <4bd9a21a$0$9898$80265adb@spool.cs.wisc.edu> Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Trace: individual.net FbkC4us5jtGiOvry02lN0AckKJJTba9FI80Xsl93vh+F2vxVuS Cancel-Lock: sha1:5tS4K0bWv8/mXMw9vDVKr377ykQ= User-Agent: Pan/0.133 (House of Butterflies) On Thu, 29 Apr 2010 15:13:30 +0000, Peter Keller wrote: > RG wrote: >> You want a displaced (and adjustable) array. >> >> ? (setf a1 (make-array 30)) >> #(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) ? >> (dotimes (i 30) (setf (aref a1 i) i)) ... >> ? a1 >> #(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 >> 26 27 28 29) >> ? (setf a2 (make-array 10 :displaced-to a1 :displaced-index-offset 15 >> :adjustable t)) >> #(15 16 17 18 19 20 21 22 23 24) >> ? (adjust-array a1 '(15) :displaced-to a1 :displaced-index-offset 10) >> #(10 11 12 13 14 15 16 17 18 19 20 21 22 23 24) > > I see. > > If I knew how big the final sizes of the arrays were I could use this > method, but sadly I don't. I'll file away the method for another day. It > looks like under my circumstances, a new array into which I copy all of > my disparate pieces looks to be one of the only solutions. Sometimes I face a similar problem (collecting an number of items that are either unknown a prior, or I am lazy to calculate). I usually solve it the following way: create array with extra elements, keep using them until I run out, then create a new array with a buffer of extra elements, copy and continue. This way, you will copy occasionally, but not all the time. Example: (use-package '(:bind)) (defun prepend-elements (vector n &optional (extra 256)) (bind (((:values displaced-to index-offset) (array-displacement vector)) (new-length (+ n (length vector)))) (if (and displaced-to (<= n index-offset)) (make-array new-length :displaced-index-offset (- index-offset n) :displaced-to displaced-to) (let ((new-vector (make-array (+ extra new-length)))) (replace new-vector vector :start1 (+ extra n)) (make-array new-length :displaced-index-offset extra :displaced-to new-vector))))) (defparameter *a* #(1 2 3)) (setf *a* (prepend-elements *a* 7)) (array-displacement *a*) ; #(0 0 0 ...), 256 You can add bells and whistles, eg prepended element initialization, etc. Tamas