1
0
Fork 0
cl-sites/www.cs.cmu.edu/Groups/AI/html/cltl/clm/node163.html
2023-10-25 11:23:21 +02:00

221 lines
11 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3O//DTD W3 HTML 2.0//EN">
<!Converted with LaTeX2HTML 0.6.5 (Tue Nov 15 1994) by Nikos Drakos (nikos@cbl.leeds.ac.uk), CBLU, University of Leeds >
<HEAD>
<TITLE>17.6. Changing the Dimensions of an Array</TITLE>
</HEAD>
<BODY>
<meta name="description" value=" Changing the Dimensions of an Array">
<meta name="keywords" value="clm">
<meta name="resource-type" value="document">
<meta name="distribution" value="global">
<P>
<b>Common Lisp the Language, 2nd Edition</b>
<BR> <HR><A NAME=tex2html3559 HREF="node164.html"><IMG ALIGN=BOTTOM ALT="next" SRC="icons/next_motif.gif"></A> <A NAME=tex2html3557 HREF="node157.html"><IMG ALIGN=BOTTOM ALT="up" SRC="icons/up_motif.gif"></A> <A NAME=tex2html3553 HREF="node162.html"><IMG ALIGN=BOTTOM ALT="previous" SRC="icons/previous_motif.gif"></A> <A NAME=tex2html3561 HREF="node1.html"><IMG ALIGN=BOTTOM ALT="contents" SRC="icons/contents_motif.gif"></A> <A NAME=tex2html3562 HREF="index.html"><IMG ALIGN=BOTTOM ALT="index" SRC="icons/index_motif.gif"></A> <BR>
<B> Next:</B> <A NAME=tex2html3560 HREF="node164.html"> Strings</A>
<B>Up:</B> <A NAME=tex2html3558 HREF="node157.html"> Arrays</A>
<B> Previous:</B> <A NAME=tex2html3554 HREF="node162.html"> Fill Pointers</A>
<HR> <P>
<H1><A NAME=SECTION002160000000000000000>17.6. Changing the Dimensions of an Array</A></H1>
<P>
This function may be used to resize or reshape an array.
Its options are similar to those of <tt>make-array</tt>.
<P>
<BR><b>[Function]</b><BR>
<tt>adjust-array <i>array</i> <i>new-dimensions</i> &amp;key :element-type :initial-element :initial-contents :fill-pointer :displaced-to :displaced-index-offset</tt><P><tt>adjust-array</tt> takes an array and a number of other arguments
as for <tt>make-array</tt>. The number of dimensions
specified by <i>new-dimensions</i> must equal the rank of <i>array</i>.
<P>
<tt>adjust-array</tt> returns an array of the same type and rank as <i>array</i>,
with the specified <i>new-dimensions</i>. In effect, the <i>array</i> argument
itself is modified to conform to the new specifications, but this may
be achieved either by modifying the <i>array</i> or by creating a new
array and modifying the <i>array</i> argument to be <i>displaced</i> to the
new array.
<P>
In the simplest case, one specifies only the <i>new-dimensions</i>
and possibly an <tt>:initial-element</tt> argument.
Those elements of <i>array</i> that
are still in bounds appear in the new array. The elements of
the new array that are not in the bounds of <i>array</i> are initialized
to the <tt>:initial-element</tt>; if this argument is not provided,
then the initial contents of any new elements are undefined.
<P>
If <tt>:element-type</tt> is specified, then <i>array</i> must be such that it could have
been originally created with that type; otherwise an error is signaled.
Specifying <tt>:element-type</tt> to <tt>adjust-array</tt> serves only to require such an
error check.
<P>
If <tt>:initial-contents</tt> or <tt>:displaced-to</tt>
is specified, then it is treated as for
<tt>make-array</tt>. In this case none of the original contents of
<i>array</i> appears in the new array.
<P>
If <tt>:fill-pointer</tt> is specified, the fill pointer of the <i>array</i>
is reset as specified. An error is signaled if <i>array</i> had no
fill pointer already.
<P>
<img align=bottom alt="change_begin" src="gif/change_begin.gif"><br>
X3J13 voted in June 1988
(ADJUST-ARRAY-FILL-POINTER) <A NAME=17991>&#160;</A>
to clarify the treatment of the <tt>:fill-pointer</tt>
argument as follows.
<P>
If the <tt>:fill-pointer</tt> argument is not supplied, then the fill pointer
of the <i>array</i> is left alone. It is an error
to try to adjust the <i>array</i> to a total size that is smaller
than its fill pointer.
<P>
If the <tt>:fill-pointer</tt> argument is supplied, then its value
must be either an integer, <tt>t</tt>, or <tt>nil</tt>. If it is an integer,
then it is the new value for the fill pointer;
it must be non-negative and no greater than the new size to which the
<i>array</i> is being adjusted.
If it is <tt>t</tt>, then the fill pointer is set equal to the new size
for the <i>array</i>. If it is <tt>nil</tt>, then the fill pointer is
left alone; it is as if the argument had not been supplied.
Again, it is an error
to try to adjust the <i>array</i> to a total size that is smaller
than its fill pointer.
<P>
An error is signaled if a non-<tt>nil :fill-pointer</tt> value
is supplied and the <i>array</i> to be adjusted does not already
have a fill pointer.
<P>
This extended treatment of the <tt>:fill-pointer</tt>
argument to <tt>adjust-array</tt> is consistent with the previously
existing treatment of the <tt>:fill-pointer</tt> argument to <tt>make-array</tt>.
<br><img align=bottom alt="change_end" src="gif/change_end.gif">
<P>
<tt>adjust-array</tt> may, depending on the implementation and the arguments,
simply alter the given array or create and return a new one.
In the latter case the given array will be altered so as to be displaced
to the new array and have the given new dimensions.
<P>
<img align=bottom alt="old_change_begin" src="gif/old_change_begin.gif"><br>
It is not permitted to call <tt>adjust-array</tt> on an array that was not
created with the <tt>:adjustable</tt> option. The predicate
<tt>adjustable-array-p</tt> may be used to determine whether or not
an array is adjustable.
<br><img align=bottom alt="old_change_end" src="gif/old_change_end.gif">
<P>
<img align=bottom alt="change_begin" src="gif/change_begin.gif"><br>
X3J13 voted in January 1989
(ADJUST-ARRAY-NOT-ADJUSTABLE) <A NAME=18015>&#160;</A>
to allow <tt>adjust-array</tt> to be applied to any array.
If <tt>adjust-array</tt> is applied to an array that was
originally created with <tt>:adjustable</tt> true,
the array returned is <tt>eq</tt> to its first argument. It is not specified
whether <tt>adjust-array</tt> returns an array <tt>eq</tt> to its first argument for any
other arrays. If the array returned by <tt>adjust-array</tt> is not <tt>eq</tt> to its
first argument, the original array is unchanged and does not share
storage with the new array.
<P>
Under this new definition, it is wise to treat <tt>adjust-array</tt>
in the same manner as <tt>delete</tt> and <tt>nconc</tt>: one should carefully
retain the returned value, for example by writing
<P><pre>
(setq my-array (adjust-array my-array ...))
</pre><P>
rather than relying solely on a side effect.
<br><img align=bottom alt="change_end" src="gif/change_end.gif">
<P>
If <tt>adjust-array</tt> is applied to an <i>array</i> that is displaced
to another array <i>x</i>, then afterwards neither <i>array</i> nor the returned
result is displaced to <i>x</i> unless such displacement is explicitly
re-specified in the call to <tt>adjust-array</tt>.
<P>
For example, suppose that the 4-by-4 array <tt>m</tt> looks like this:
<P><pre>
#2A( ( alpha beta gamma delta )
( epsilon zeta eta theta )
( iota kappa lambda mu )
( nu xi omicron pi ) )
</pre><P>
Then the result of
<P><pre>
(adjust-array m '(3 5) :initial-element 'baz)
</pre><P>
is a 3-by-5 array with contents
<P><pre>
#2A( ( alpha beta gamma delta baz )
( epsilon zeta eta theta baz )
( iota kappa lambda mu baz ) )
</pre><P>
Note that if array <tt>a</tt> is created displaced to array <tt>b</tt> and subsequently
array <tt>b</tt> is given to <tt>adjust-array</tt>, array <tt>a</tt> will still be
displaced to array <tt>b</tt>; the effects of this displacement and
the rule of row-major storage order must be taken into account.
<P>
<img align=bottom alt="change_begin" src="gif/change_begin.gif"><br>
X3J13 voted in June 1988 (ADJUST-ARRAY-DISPLACEMENT) <A NAME=18050>&#160;</A>
to clarify the interaction of <tt>adjust-array</tt> with array displacement.
<P>
Suppose that an array <i>A</i> is to be adjusted. There are four cases
according to whether or not <i>A</i> was displaced before adjustment
and whether or not the result is displaced after adjustment.
<UL><LI>
Suppose <i>A</i> is not displaced either before or after.
The dimensions of <i>A</i> are altered, and
the contents are rearranged as appropriate. Additional elements of <i>A</i>
are taken from the <tt>:initial-element</tt> argument.
However, the use of the <tt>:initial-contents</tt> argument causes all old
contents to be discarded.
<P>
<LI>
Suppose <i>A</i> is not displaced before, but is displaced to array <i>C</i> after.
None of the original contents of <i>A</i> appears in <i>A</i> afterwards; <i>A</i>
now contains (some of) the contents of <i>C</i>, without any rearrangement of
<i>C</i>.
<P>
<LI>
Suppose <i>A</i> is displaced to array <i>B</i> before the call,
and is displaced to array <i>C</i> after the call.
(Note that <i>B</i> and <i>C</i> may be the same array.)
The contents of <i>B</i> do not appear in
<i>A</i> afterwards (unless such contents also happen to be in <i>C</i>,
as when <i>B</i> and <i>C</i> are the same, for example). If
<tt>:displaced-index-offset</tt> is not specified in the call to
<tt>adjust-array</tt>, it defaults
to zero; the old offset (into <i>B</i>) is not retained.
<P>
<LI>
Suppose <i>A</i> is displaced to array <i>B</i> before the call,
but is not displaced afterwards. In this case <i>A</i> gets
a new ``data region'' and (some of) the
contents of <i>B</i> are copied into it as appropriate to
maintain the existing old contents. Additional elements of <i>A</i>
are taken from the <tt>:initial-element</tt> argument.
However, the use of the <tt>:initial-contents</tt> argument causes all old
contents to be discarded.
</UL>
<P>
If array <i>X</i> is displaced to array <i>Y</i>, and array <i>Y</i> is displaced
to array <i>Z</i>, and array <i>Y</i> is altered by <tt>adjust-array</tt>, array
<i>X</i> must now refer to the adjusted contents of <i>Y</i>. This means that an
implementation may not collapse the chain to make <i>X</i> refer to <i>Z</i>
directly and forget that the chain of reference passes through array <i>Y</i>.
(Caching techniques are of course permitted, as long as they preserve the
semantics specified here.)
<P>
If <i>X</i> is displaced to <i>Y</i>, it is an error to adjust <i>Y</i> in such a
way that it no longer has enough elements to satisfy <i>X</i>. This error may be
signaled at the time of the adjustment, but this is not required.
<P>
Note that omitting the <tt>:displaced-to</tt> argument to <tt>adjust-array</tt> is
equivalent to specifying <tt>:displaced-to nil</tt>; in either case, the array is
not displaced after the call regardless of whether it was displaced before
the call.
<br><img align=bottom alt="change_end" src="gif/change_end.gif">
<P>
<P>
<BR> <HR><A NAME=tex2html3559 HREF="node164.html"><IMG ALIGN=BOTTOM ALT="next" SRC="icons/next_motif.gif"></A> <A NAME=tex2html3557 HREF="node157.html"><IMG ALIGN=BOTTOM ALT="up" SRC="icons/up_motif.gif"></A> <A NAME=tex2html3553 HREF="node162.html"><IMG ALIGN=BOTTOM ALT="previous" SRC="icons/previous_motif.gif"></A> <A NAME=tex2html3561 HREF="node1.html"><IMG ALIGN=BOTTOM ALT="contents" SRC="icons/contents_motif.gif"></A> <A NAME=tex2html3562 HREF="index.html"><IMG ALIGN=BOTTOM ALT="index" SRC="icons/index_motif.gif"></A> <BR>
<B> Next:</B> <A NAME=tex2html3560 HREF="node164.html"> Strings</A>
<B>Up:</B> <A NAME=tex2html3558 HREF="node157.html"> Arrays</A>
<B> Previous:</B> <A NAME=tex2html3554 HREF="node162.html"> Fill Pointers</A>
<HR> <P>
<HR>
<P><ADDRESS>
AI.Repository@cs.cmu.edu
</ADDRESS>
</BODY>