9.2 Mapping over Sequences

These functions “map” the function you specify over the elements of lists or arrays. They are all variations on the theme of the built-in function mapcar.

Function: cl-mapcar function seq &rest more-seqs

This function calls function on successive parallel sets of elements from its argument sequences. Given a single seq argument it is equivalent to mapcar; given n sequences, it calls the function with the first elements of each of the sequences as the n arguments to yield the first element of the result list, then with the second elements, and so on. The mapping stops as soon as the shortest sequence runs out. The argument sequences may be any mixture of lists, strings, and vectors; the return sequence is always a list.

Common Lisp’s mapcar accepts multiple arguments but works only on lists; Emacs Lisp’s mapcar accepts a single sequence argument. This package’s cl-mapcar works as a compatible superset of both.

Function: cl-map result-type function seq &rest more-seqs

This function maps function over the argument sequences, just like cl-mapcar, but it returns a sequence of type result-type rather than a list. result-type must be one of the following symbols: vector, string, list (in which case the effect is the same as for cl-mapcar), or nil (in which case the results are thrown away and cl-map returns nil).

Function: cl-maplist function list &rest more-lists

This function calls function on each of its argument lists, then on the CDRs of those lists, and so on, until the shortest list runs out. The results are returned in the form of a list. Thus, cl-maplist is like cl-mapcar except that it passes in the list pointers themselves rather than the CARs of the advancing pointers.

Function: cl-mapc function seq &rest more-seqs

This function is like cl-mapcar, except that the values returned by function are ignored and thrown away rather than being collected into a list. The return value of cl-mapc is seq, the first sequence. This function is more general than the Emacs primitive mapc. (Note that this function is called cl-mapc even in cl.el, rather than mapc* as you might expect.)

Function: cl-mapl function list &rest more-lists

This function is like cl-maplist, except that it throws away the values returned by function.

Function: cl-mapcan function seq &rest more-seqs

This function is like cl-mapcar, except that it concatenates the return values (which must be lists) using nconc, rather than simply collecting them into a list.

Function: cl-mapcon function list &rest more-lists

This function is like cl-maplist, except that it concatenates the return values using nconc.

Function: cl-some predicate seq &rest more-seqs

This function calls predicate on each element of seq in turn; if predicate returns a non-nil value, cl-some returns that value, otherwise it returns nil. Given several sequence arguments, it steps through the sequences in parallel until the shortest one runs out, just as in cl-mapcar. You can rely on the left-to-right order in which the elements are visited, and on the fact that mapping stops immediately as soon as predicate returns non-nil.

Function: cl-every predicate seq &rest more-seqs

This function calls predicate on each element of the sequence(s) in turn; it returns nil as soon as predicate returns nil for any element, or t if the predicate was true for all elements.

Function: cl-notany predicate seq &rest more-seqs

This function calls predicate on each element of the sequence(s) in turn; it returns nil as soon as predicate returns a non-nil value for any element, or t if the predicate was nil for all elements.

Function: cl-notevery predicate seq &rest more-seqs

This function calls predicate on each element of the sequence(s) in turn; it returns a non-nil value as soon as predicate returns nil for any element, or nil if the predicate was true for all elements.

Function: cl-reduce function seq &key :from-end :start :end :initial-value :key

This function returns the result of calling function on the first and second elements of seq, then calling function with that result and the third element of seq, then with that result and the fourth element of seq, etc.

Here is an example. Suppose function is * and seq is the list (2 3 4 5). The first two elements of the list are combined with (* 2 3) = 6; this is combined with the next element, (* 6 4) = 24, and that is combined with the final element: (* 24 5) = 120. Note that the * function happens to be self-reducing, so that (* 2 3 4 5) has the same effect as an explicit call to cl-reduce.

If :from-end is true, the reduction is right-associative instead of left-associative:

(cl-reduce '- '(1 2 3 4))
        ≡ (- (- (- 1 2) 3) 4) ⇒ -8
(cl-reduce '- '(1 2 3 4) :from-end t)
        ≡ (- 1 (- 2 (- 3 4))) ⇒ -2

If :key is specified, it is a function of one argument, which is called on each of the sequence elements in turn.

If :initial-value is specified, it is effectively added to the front (or rear in the case of :from-end) of the sequence. The :key function is not applied to the initial value.

If the sequence, including the initial value, has exactly one element then that element is returned without ever calling function. If the sequence is empty (and there is no initial value), then function is called with no arguments to obtain the return value.

All of these mapping operations can be expressed conveniently in terms of the cl-loop macro. In compiled code, cl-loop will be faster since it generates the loop as in-line code with no function calls.