common-lisp
Отображение функций по спискам
Поиск…
обзор
Набор функций отображения высокого уровня доступен в Common Lisp, чтобы применить функцию к элементам одного или нескольких списков. Они отличаются тем, как функция применяется к спискам и как получается конечный результат. Следующая таблица суммирует различия и показывает для каждой из них эквивалентную форму LOOP. f - применяемая функция, которая должна иметь число аргументов, равное количеству списков; «Применяется к машине» означает, что оно применяется в свою очередь к элементам списков, «применяется к cdr» означает, что оно применяется в свою очередь к спискам, их cdr, их cddr и т. Д .; столбец «возвращает» показывает, является ли глобальный результат полученным путем перечисления результатов, объединяя их (поэтому они должны быть списками!) или просто используются для побочных эффектов (и в этом случае возвращается первый список).
функция | Применительно к | Возвращает | Эквивалентный LOOP |
---|---|---|---|
(mapcar fl 1 ... l n ) | автомобиль | список результатов | (цикл для x 1 в l 1 ... для x n в l n собирать (fx 1 ... x n )) |
(maplist fl 1 ... l n ) | корд | список результатов | (цикл для x 1 на l 1 ... для x n на l n собирать (fx 1 ... x n )) |
(mapcan fl 1 ... l n ) | автомобиль | конкатенация результатов | (цикл для x 1 в l 1 ... для x n в l n nconc (fx 1 ... x n )) |
(mapcon fl 1 ... l n ) | корд | конкатенация результатов | (цикл для x 1 на l 1 ... для x n на l n nconc (fx 1 ... x n )) |
(mapc fl 1 ... l n ) | автомобиль | л 1 | (цикл для x 1 в l 1 ... для x n в l n do (fx 1 ... x n ) наконец (return l 1 )) |
(mapl fl 1 ... l n ) | корд | л 1 | (цикл для x 1 на l 1 ... для x n на l n do (fx 1 ... x n ) наконец (return l 1 )) |
Обратите внимание, что во всех случаях списки могут иметь разную длину, и приложение заканчивается при завершении кратчайшего списка.
Доступна еще одна пара функций карты: map
, которая может быть применена к последовательностям (строки, векторы, списки), аналогичные mapcar
, и которые могут возвращать любой тип последовательности, указанный как первый аргумент, и map-into
, аналогичный map
, но это разрушительно изменяет свой первый аргумент последовательности, чтобы сохранить результаты применения функции.
Примеры MAPCAR
MAPCAR является наиболее часто используемой функцией семьи:
CL-USER> (mapcar #'1+ '(1 2 3))
(2 3 4)
CL-USER> (mapcar #'cons '(1 2 3) '(a b c))
((1 . A) (2 . B) (3 . C))
CL-USER> (mapcar (lambda (x y z) (+ (* x y) z))
'(1 2 3)
'(10 20 30)
'(100 200 300))
(110 240 390)
CL-USER> (let ((list '(a b c d e f g h i))) ; randomize this list
(mapcar #'cdr
(sort (mapcar (lambda (x)
(cons (random 100) x))
list)
#'<=
:key #'car)))
(I D A G B H E C F)
mapcar
использование mapcar
заключается в транспонировании матрицы, представленной в виде списка списков:
CL-USER> (defun transpose (list-of-lists)
(apply #'mapcar #'list list-of-lists))
ROTATE
CL-USER> (transpose '((a b c) (d e f) (g h i)))
((A D G) (B E H) (C F I))
; +---+---+---+ +---+---+---+
; | A | B | C | | A | D | G |
; +---+---+---+ +---+---+---+
; | D | E | F | becomes | B | E | H |
; +---+---+---+ +---+---+---+
; | G | H | I | | C | F | I |
; +---+---+---+ +---+---+---+
Для пояснения см. Этот ответ .
Примеры MAPLIST
CL-USER> (maplist (lambda (list) (cons 0 list)) '(1 2 3 4))
((0 1 2 3 4) (0 2 3 4) (0 3 4) (0 4))
CL-USER> (maplist #'append
'(a b c d -)
'(1 2 3))
((A B C D - 1 2 3) (B C D - 2 3) (C D - 3))
Примеры MAPCAN и MAPCON
MAPCAN:
CL-USER> (mapcan #'reverse '((1 2 3) (a b c) (100 200 300)))
(3 2 1 C B A 300 200 100)
CL-USER> (defun from-to (min max)
(loop for i from min to max collect i))
FROM-TO
CL-USER> (from-to 1 5)
(1 2 3 4 5)
CL-USER> (mapcan #'from-to '(1 2 3) '(5 5 5))
(1 2 3 4 5 2 3 4 5 3 4 5)
Одним из видов использования MAPCAN является создание списка результатов без значений NIL:
CL-USER> (let ((l1 '(10 20 40)))
(mapcan (lambda (x)
(if (member x l1)
(list x)
nil))
'(2 4 6 8 10 12 14 16 18 20
18 16 14 12 10 8 6 4 2)))
(10 20 10)
MAPCON:
CL-USER> (mapcon #'copy-list '(1 2 3))
(1 2 3 2 3 3)
CL-USER> (mapcon (lambda (l1 l2) (list (length l1) (length l2))) '(a b c d) '(d e f))
(4 3 3 2 2 1)
Примеры MAPC и MAPL
MAPC:
CL-USER> (mapc (lambda (x) (print (* x x))) '(1 2 3 4))
1
4
9
16
(1 2 3 4)
CL-USER> (let ((sum 0))
(mapc (lambda (x y) (incf sum (* x y)))
'(1 2 3)
'(100 200 300))
sum)
1400 ; => (1 x 100) + (2 x 200) + (3 x 300)
MAPL:
CL-USER> (mapl (lambda (list) (print (reduce #'+ list))) '(1 2 3 4 5))
15
14
12
9
5
(1 2 3 4 5)