14.2 Объединение, отображение и приведение последовательностей

Функции в этом разделе могут обрабатывать произвольное количество последовательностей за исключением функции reduce, которая была включена сюда из-за концептуальной связи с функциями отображения.

[Функция] concatenate result-type &rest sequences

Результатом является новая последовательность, которая содержит по порядку все элементы указанных последовательностей. Результат не содержит связей с аргументами (в этом concatenate отличается от append). Тип результата указывается в аргументе result-type, который должен быть подтипом sequence, как для функции coerce. Необходимо, чтобы элементы исходных последовательностей принадлежали указанному типу result-type.

Если указана только одна последовательность, и она имеет тот же тип, что указан в result-type, concatenate всё равно копирует аргумент и возвращает новую последовательность. Если вам не требуется копия, а просто необходимо преобразовать тип последовательности, лучше использовать coerce.

X3J13 voted in June 1989 to specify that concatenate should signal an error if the sequence type specifies the number of elements and the sum of the argument lengths is different.


[Функция] map result-type function sequence &rest more-sequences

Функция function должна принимать только аргументов, сколько последовательностей было передано в map. Результат функции map — последовательность, элементы которой являются результатами применения функции function к соответствующим элементам исходных последовательностей. Длина итоговой последовательности равна длине самой короткой исходной.

Если функция function имеет побочные эффекты, она может рассчитывать на то, что сначала будет вызвана со всеми элементами в 0-ой позиции, затем со всеми в 1-ой и так далее.

Тип итоговой последовательности указывается в аргументе result-type (и должен быть подтипом sequence). Кроме того, для типа можно указать nil, и это означает, что результата быть не должно. В таком случае функция function вызывается только для побочных эффектов, и map возвращает nil. В этом случае map похожа на mapc.

X3J13 voted in June 1989 to specify that map should signal an error if the sequence type specifies the number of elements and the minimum of the argument lengths is different.

X3J13 voted in January 1989 to restrict user side effects; see section 7.9.

Пользователь ограничен в создании побочных действий так, как это описано в разделе 7.9

Например:

(map ’list #’- ’(1 2 3 4))  (-1 -2 -3 -4)
(map ’string
     #’(lambda (x) (if (oddp x) #\1 #\0))
     ’(1 2 3 4))
    "1010"


[Функция] map-into result-sequence function &rest sequences

Функция map-into вычисляет последовательность с помощью применения функции function к соответствующим элементам исходных последовательностей и помещает результат в последовательность result-sequence. Функция возвращается result-sequence.

Аргументы result-sequence и все sequences должны быть списками или векторами (одномерными массивами). Функция function должна принимать столько аргументов, сколько было указано исходных последовательностей. Если result-sequence и другие аргументы sequences не одинаковой длины, цикл закончится на самой короткой последовательности. Если result-sequence является вектором с указателем заполнения, то этот указатель во время цикла игнорируется, а после завершения устанавливается на то количество элементов, которые были получены от функции function.

Если функция function имеет побочные эффекты, она может рассчитывать на то, что сначала будет вызвана со всеми элементами в 0-ой позиции, затем со всеми в 1-ой и так далее.

Функция map-into отличается от map тем, что модифицирует уже имеющуюся последовательность, а не создаёт новую. Кроме того, map-into может быть вызвана только с двумя аргументами (result-sequence и function), тогда как map требует как минимум три параметра.

Если result-sequence является nil, map-into немедленно возвращает nil, потому что длина nil последовательности равняется нулю.


[Функция] some predicate sequence &rest more-sequences
[Функция] every predicate sequence &rest more-sequences
[Функция] notany predicate sequence &rest more-sequences
[Функция] notevery predicate sequence &rest more-sequences

Всё это предикаты. Функция predicate должна принимать столько аргументов, сколько было указано последовательностей. Функция predicate сначала применяется к элементам 0-ой позиции, затем, возможно, к элементам 1-ой позиции, и так далее, до тех пор пока не сработает условие завершения цикла или не закончится одна из последовательностей sequences.

Если predicate имеет побочные эффекты, он может рассчитывать на то, что сначала будет вызвана со всеми элементами в 0-ой позиции, затем со всеми в 1-ой и так далее.

some завершается, как только применение predicate вернёт не-nil значение. Тогда some возвращает значение, на котором произошла остановка. Если цикл достиг конца последовательности и ни одно применение predicate не вернуло не-nil, тогда возвращается значение nil. Таким образом, можно сказать, что предикат some истинен, если какой-либо (some) вызов predicate истинен.

every возвращает nil, как только применение predicate возвращает nil. Если цикл достиг конца последовательности, every возвращает не-nil. Таким образом, можно сказать, что предикат every истинен, если каждый (every) вызов predicate истинен.

notany возвращает nil, как только применение predicate возвращает не-nil. Если цикл достиг конца последовательности, notany возвращает не-nil. Таким образом, можно сказать, что предикат notany истинен, если ни какой (notany) вызов predicate не истинен.

notevery возвращает не-nil, как только применение predicate возвращает nil. Если цикл достиг конца последовательности, notevery возвращает nil. Таким образом, можно сказать, что предикат notevery истинен, если ни каждый (notany) вызов predicate истинен.

X3J13 voted in January 1989 to restrict user side effects; see section 7.9.

Пользователь ограничен в создании побочных действий так, как это описано в разделе 7.9


[Функция] reduce function sequence &key :from-end :start :end :initial-value

Функция reduce объединяет все элементы последовательности использую заданную (бинарную binary) операцию. Например + может суммировать все элементы последовательности.

Указанная подпоследовательность последовательности sequence объединяется или «редуцируется» с помощью функции function, которая должна принимать два аргумента. Приведение (редуцирование, объединение) является левоассоциативным, если только :from-end не содержит истину, в последнем случае операция становиться правоассоциативной. По-умолчанию :from-end равно nil. Если задан аргумент :initial-value, то он логически помещается перед подпоследовательностью (или после в случае истинности :from-end) и включается в операцию редуцирования.

Если указанная подпоследовательность содержит только один элемент и параметр :initial-value не задан, тогда этот элемент возвращается, и функция function ни разу не вызывается. Если заданная подпоследовательность пуста, и задан параметр :initial-value, тогда возвращается :initial-value, и функция function не вызывается.

Если заданная подпоследовательность пуста, и параметр :initial-value не задан, тогда функция function вызывается без аргументов, и reduce возвращает то, что вернула эта функция. Это единственное исключение из правила о том, что функция function вызывается с двумя аргументами.

(reduce #’+ ’(1 2 3 4))  10
(reduce #’- ’(1 2 3 4))  (- (- (- 1 2) 3) 4)  -8
(reduce #’- ’(1 2 3 4) :from-end t)     ;Альтернативная сумма
    (- 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))))

Если функция function имеет побочные эффекта, можно положится на порядок вызовов функции так, как было продемонстрировано выше.

Имя «reduce» было позаимствовано из APL.

X3J13 voted in March 1988 to extend the reduce function to take an additional keyword argument named :key. 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 :from-end argument; the values returned by this function are combined by the reduction function. However, the :key function is not applied to the :initial-value argument (if any).

X3J13 voted in January 1989 to restrict user side effects; see section 7.9.

Пользователь ограничен в создании побочных действий так, как это описано в разделе 7.9