1
0
Fork 0
cl-sites/www.cs.cmu.edu/Groups/AI/html/cltl/clm/node143.html

260 lines
14 KiB
HTML
Raw Normal View History

2023-10-25 11:23:21 +02:00
<!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>14.2. Concatenating, Mapping, and Reducing Sequences</TITLE>
</HEAD>
<BODY>
<meta name="description" value=" Concatenating, Mapping, and Reducing Sequences">
<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=tex2html3313 HREF="node144.html"><IMG ALIGN=BOTTOM ALT="next" SRC="icons/next_motif.gif"></A> <A NAME=tex2html3311 HREF="node141.html"><IMG ALIGN=BOTTOM ALT="up" SRC="icons/up_motif.gif"></A> <A NAME=tex2html3305 HREF="node142.html"><IMG ALIGN=BOTTOM ALT="previous" SRC="icons/previous_motif.gif"></A> <A NAME=tex2html3315 HREF="node1.html"><IMG ALIGN=BOTTOM ALT="contents" SRC="icons/contents_motif.gif"></A> <A NAME=tex2html3316 HREF="index.html"><IMG ALIGN=BOTTOM ALT="index" SRC="icons/index_motif.gif"></A> <BR>
<B> Next:</B> <A NAME=tex2html3314 HREF="node144.html"> Modifying Sequences</A>
<B>Up:</B> <A NAME=tex2html3312 HREF="node141.html"> Sequences</A>
<B> Previous:</B> <A NAME=tex2html3306 HREF="node142.html"> Simple Sequence Functions</A>
<HR> <P>
<H1><A NAME=SECTION001820000000000000000>14.2. Concatenating, Mapping, and Reducing Sequences</A></H1>
<P>
The functions in this section each operate on an arbitrary number of
sequences except for <tt>reduce</tt>, which is included here because
of its conceptual relationship to the mapping functions.
<P>
<BR><b>[Function]</b><BR>
<tt>concatenate <i>result-type</i> &amp;rest <i>sequences</i></tt><P>The result is a new sequence that contains all the elements of all the
sequences in order. All of the sequences are copied from; the result
does not share any structure with any of the argument sequences (in this
<tt>concatenate</tt> differs from <tt>append</tt>). The type of the result is
specified by <i>result-type</i>, which must be a subtype of <tt>sequence</tt>,
as for the function <tt>coerce</tt>.
It must be possible for every element of the argument sequences to be an
element of a sequence of type <i>result-type</i>.
<P>
If only one <i>sequence</i> argument is provided
and it has the type specified by <i>result-type</i>,
<tt>concatenate</tt> is required to copy the argument rather than simply
returning it. If a copy is not required, but only possibly type conversion,
then the <tt>coerce</tt> function may be appropriate.
<P>
<img align=bottom alt="change_begin" src="gif/change_begin.gif"><br>
X3J13 voted in June 1989 (SEQUENCE-TYPE-LENGTH) <A NAME=15492>&#160;</A> to specify that
<tt>concatenate</tt> should signal an error if the sequence type specifies the
number of elements and the sum of the argument lengths is different.
<br><img align=bottom alt="change_end" src="gif/change_end.gif">
<P>
<BR><b>[Function]</b><BR>
<tt>map <i>result-type</i> <i>function</i> <i>sequence</i> &amp;rest <i>more-sequences</i></tt><P>The <i>function</i> must take as many arguments as there are sequences
provided; at least one sequence must be provided.
The result of <tt>map</tt> is a sequence such that element <i>j</i> is the result
of applying <i>function</i> to element <i>j</i> of each of the argument
sequences. The result sequence is as long as the shortest of the
input sequences.
<P>
If the <i>function</i> has side effects, it can count on being called
first on all the elements numbered <tt>0</tt>, then on all those
numbered <tt>1</tt>, and so on.
<P>
The type of the result sequence is specified by the argument <i>result-type</i>
(which must be a subtype of the type <tt>sequence</tt>),
as for the function <tt>coerce</tt>.
In addition, one may specify <tt>nil</tt> for the result type, meaning that no
result sequence is to be produced; in this case the <i>function</i> is invoked
only for effect, and <tt>map</tt> returns <tt>nil</tt>. This gives an effect similar
to that of <tt>mapc</tt>.
<P>
<img align=bottom alt="change_begin" src="gif/change_begin.gif"><br>
X3J13 voted in June 1989 (SEQUENCE-TYPE-LENGTH) <A NAME=15514>&#160;</A> to specify that
<tt>map</tt> should signal an error if the sequence type specifies the number of
elements and the minimum of the argument lengths is different.
<P>
X3J13 voted in January 1989
(MAPPING-DESTRUCTIVE-INTERACTION) <A NAME=15518>&#160;</A>
to restrict user side effects; see section <A HREF="node92.html#STRUCTURETRAVERSALSECTION">7.9</A>.
<br><img align=bottom alt="change_end" src="gif/change_end.gif">
<P>
<hr>
<b>Compatibility note:</b> In MacLisp, Lisp Machine Lisp, Interlisp, and indeed even
Lisp 1.5, the function <tt>map</tt> has always meant a non-value-returning
version. However, standard computer science literature, including
in particular
the recent wave of papers on ``functional programming,'' have come
to use <tt>map</tt> to mean
what in the past Lisp implementations have called <tt>mapcar</tt>.
To simplify things henceforth, Common Lisp follows current usage,
and what was formerly called <tt>map</tt> is named <tt>mapl</tt> in Common Lisp.
<hr>
<P>
For example:
<P><pre>
(map 'list #'- '(1 2 3 4)) => (-1 -2 -3 -4)
(map 'string
#'(lambda (x) (if (oddp x) #\1 #\0))
'(1 2 3 4))
=> &quot;1010&quot;
</pre><P>
<P>
<img align=bottom alt="change_begin" src="gif/change_begin.gif"><br>
<BR><b>[Function]</b><BR>
<tt>map-into <i>result-sequence</i> <i>function</i> &amp;rest <i>sequences</i></tt><P> X3J13 voted in June 1989 (MAP-INTO) <A NAME=15535>&#160;</A> to add the function <tt>map-into</tt>.
It destructively modifies the <i>result-sequence</i> to contain the results of
applying <i>function</i> to corresponding elements of
the argument <i>sequences</i> in turn; it then
returns <i>result-sequence</i>.
<P>
The arguments <i>result-sequence</i>
and each element of <i>sequences</i> can each be
either a list or a vector (one-dimensional array).
The <tt>function</tt> must accept at least as many arguments as the
number of argument <i>sequences</i> supplied to <tt>map-into</tt>.
If <i>result-sequence</i> and
the other argument <i>sequences</i> are not all the same length, the iteration
terminates when the shortest sequence is exhausted. If <i>result-sequence</i>
is a vector with a fill pointer, the fill pointer is ignored when
deciding how many iterations to perform, and afterwards the
fill pointer is set to the number of times the <i>function</i> was applied.
<P>
If the <i>function</i> has side effects, it can count on being called
first on all the elements numbered <tt>0</tt>, then on all those
numbered <tt>1</tt>, and so on.
<P>
If <i>result-sequence</i> is longer than the shortest element of <i>sequences</i>,
extra elements at the end of <i>result-sequence</i> are unchanged.
<P>
The function <tt>map-into</tt> differs from <tt>map</tt> in that it modifies
an existing sequence rather than creating a new one. In addition,
<tt>map-into</tt> can be called with only two arguments (<i>result-sequence</i>
and <i>function</i>), while <tt>map</tt> requires at least three arguments.
<P>
If <i>result-sequence</i> is <tt>nil</tt>, <tt>map-into</tt> immediately returns
<tt>nil</tt>, because <tt>nil</tt> is a sequence of length zero.
<br><img align=bottom alt="change_end" src="gif/change_end.gif">
<P>
<BR><b>[Function]</b><BR>
<tt>some <i>predicate</i> <i>sequence</i> &amp;rest <i>more-sequences</i> <BR></tt><tt>every <i>predicate</i> <i>sequence</i> &amp;rest <i>more-sequences</i> <BR></tt><tt>notany <i>predicate</i> <i>sequence</i> &amp;rest <i>more-sequences</i> <BR></tt><tt>notevery <i>predicate</i> <i>sequence</i> &amp;rest <i>more-sequences</i></tt><P>These are all predicates.
The <i>predicate</i> must take as many arguments as there are sequences
provided. The <i>predicate</i> is first applied to the elements
with index <tt>0</tt> in each of the sequences, and possibly then to
the elements with index <tt>1</tt>, and so on, until a termination
criterion is met or the end of the shortest of the <i>sequences</i> is reached.
<P>
If the <i>predicate</i> has side effects, it can count on being called
first on all the elements numbered <tt>0</tt>, then on all those
numbered <tt>1</tt>, and so on.
<P>
<tt>some</tt> returns as soon as any invocation of <i>predicate</i>
returns a non-<tt>nil</tt> value; <tt>some</tt> returns that value.
If the end of a sequence is reached, <tt>some</tt> returns <tt>nil</tt>.
Thus, considered as a predicate, it is true if <i>some</i> invocation of
<i>predicate</i> is true.
<P>
<tt>every</tt> returns <tt>nil</tt> as soon as any invocation of <i>predicate</i>
returns <tt>nil</tt>.
If the end of a sequence is reached, <tt>every</tt> returns a non-<tt>nil</tt> value.
Thus, considered as a predicate, it is true if <i>every</i> invocation of
<i>predicate</i> is true.
<P>
<tt>notany</tt> returns <tt>nil</tt> as soon as any invocation of <i>predicate</i>
returns a non-<tt>nil</tt> value.
If the end of a sequence is reached, <tt>notany</tt> returns a non-<tt>nil</tt> value.
Thus, considered as a predicate, it is true if <i>no</i> invocation of
<i>predicate</i> is true.
<P>
<tt>notevery</tt> returns a non-<tt>nil</tt> value as soon as any invocation
of <i>predicate</i> returns <tt>nil</tt>. If the end of a sequence is reached,
<tt>notevery</tt> returns
<tt>nil</tt>. Thus, considered as a predicate, it is true if <i>not every</i> invocation of
<i>predicate</i> is true.
<P>
<img align=bottom alt="change_begin" src="gif/change_begin.gif"><br>
X3J13 voted in January 1989
(MAPPING-DESTRUCTIVE-INTERACTION) <A NAME=15611>&#160;</A>
to restrict user side effects; see section <A HREF="node92.html#STRUCTURETRAVERSALSECTION">7.9</A>.
<br><img align=bottom alt="change_end" src="gif/change_end.gif">
<P>
<hr>
<b>Compatibility note:</b> The order of the arguments here is not compatible
with Interlisp and Lisp Machine Lisp. This is to stress the similarity
of these functions to <tt>map</tt>. The functions are therefore extended
here to functions of more than one argument, and to multiple sequences.
<hr>
<P>
<BR><b>[Function]</b><BR>
<tt>reduce <i>function</i> <i>sequence</i> &amp;key :from-end :start :end :initial-value</tt><P>The <tt>reduce</tt> function combines all the elements of a sequence using
a binary operation; for example, using <tt>+</tt> one can add up all the
elements.
<P>
The specified subsequence of the <i>sequence</i> is combined
or ``reduced'' using the
<i>function</i>, which must accept two arguments. The reduction is
left-associative, unless the <tt>:from-end</tt> argument is true (it defaults
to <tt>nil</tt>), in which case it is right-associative. If an
<tt>:initial-value</tt> argument is given, it is logically placed before the
subsequence (after it if <tt>:from-end</tt> is true) and included in the
reduction operation.
<P>
If the specified subsequence contains exactly one element
and the keyword argument <tt>:initial-value</tt>
is not given, then that element
is returned and the <i>function</i> is not called.
If the specified subsequence is empty and an <tt>:initial-value</tt> is given,
then the <tt>:initial-value</tt> is returned
and the <i>function</i> is not called.
<P>
If the specified subsequence is empty and no <tt>:initial-value</tt> is given,
then the <i>function</i> is called with zero
arguments, and <tt>reduce</tt> returns whatever the function does. (This is
the only case where the <i>function</i> is called with other than two
arguments.)
<P>
<P><pre>
(reduce #'+ '(1 2 3 4)) => 10
(reduce #'- '(1 2 3 4)) == (- (- (- 1 2) 3) 4) => -8
(reduce #'- '(1 2 3 4) :from-end t) ;Alternating sum
== (- 1 (- 2 (- 3 4))) => -2
(reduce #'+ '()) => 0
(reduce #'+ '(3)) => 3
(reduce #'+ '(foo)) => foo
(reduce #'list '(1 2 3 4)) => (((1 2) 3) 4)
(reduce #'list '(1 2 3 4) :from-end t) => (1 (2 (3 4)))
(reduce #'list '(1 2 3 4) :initial-value 'foo)
=> ((((foo 1) 2) 3) 4)
(reduce #'list '(1 2 3 4)
:from-end t :initial-value 'foo)
=> (1 (2 (3 (4 foo))))
</pre><P>
If the <i>function</i> produces side effects, the order of the calls
to the <i>function</i> can be correctly predicted from the reduction ordering
demonstrated above.
<P>
<img align=bottom alt="change_begin" src="gif/change_begin.gif"><br>
The name ``reduce'' for this function is borrowed from APL.
<P>
X3J13 voted in March 1988 (REDUCE-ARGUMENT-EXTRACTION) <A NAME=15643>&#160;</A>
to extend the <tt>reduce</tt> function to take
an additional keyword argument named <tt>:key</tt>. As usual, this argument
defaults to the identity function. The value of this argument must be
a function that accepts at least one argument. This function is applied once
to each element of the
sequence that is to participate in the reduction operation, in the order
implied by the <tt>:from-end</tt> argument; the values returned by this
function are combined by the reduction <i>function</i>.
However, the <tt>:key</tt> function is <i>not</i> applied
to the <tt>:initial-value</tt> argument (if any).
<P>
X3J13 voted in January 1989
(MAPPING-DESTRUCTIVE-INTERACTION) <A NAME=15653>&#160;</A>
to restrict user side effects; see section <A HREF="node92.html#STRUCTURETRAVERSALSECTION">7.9</A>.
<br><img align=bottom alt="change_end" src="gif/change_end.gif">
<P>
<BR> <HR><A NAME=tex2html3313 HREF="node144.html"><IMG ALIGN=BOTTOM ALT="next" SRC="icons/next_motif.gif"></A> <A NAME=tex2html3311 HREF="node141.html"><IMG ALIGN=BOTTOM ALT="up" SRC="icons/up_motif.gif"></A> <A NAME=tex2html3305 HREF="node142.html"><IMG ALIGN=BOTTOM ALT="previous" SRC="icons/previous_motif.gif"></A> <A NAME=tex2html3315 HREF="node1.html"><IMG ALIGN=BOTTOM ALT="contents" SRC="icons/contents_motif.gif"></A> <A NAME=tex2html3316 HREF="index.html"><IMG ALIGN=BOTTOM ALT="index" SRC="icons/index_motif.gif"></A> <BR>
<B> Next:</B> <A NAME=tex2html3314 HREF="node144.html"> Modifying Sequences</A>
<B>Up:</B> <A NAME=tex2html3312 HREF="node141.html"> Sequences</A>
<B> Previous:</B> <A NAME=tex2html3306 HREF="node142.html"> Simple Sequence Functions</A>
<HR> <P>
<HR>
<P><ADDRESS>
AI.Repository@cs.cmu.edu
</ADDRESS>
</BODY>