Buscar..


Visión general

Un conjunto de funciones de mapeo de alto nivel está disponible en Common Lisp, para aplicar una función a los elementos de una o más listas. Se diferencian en la forma en que se aplica la función a las listas y en cómo se obtiene el resultado final. La siguiente tabla resume las diferencias y muestra para cada una de ellas el formulario de LOOP equivalente. f es la función que debe aplicarse, que debe tener un número de argumentos igual al número de listas; "Aplicado al auto" significa que se aplica a su vez a los elementos de las listas, "aplicado a cdr" significa que se aplica a su vez a las listas, su cdr, su cddr, etc .; la columna "devoluciones" muestra si el resultado global es el obtenido al enumerar los resultados, concatenarlos (¡por lo tanto deben ser listas!), o simplemente usarse para efectos secundarios (y en este caso se devuelve la primera lista).

Función Aplicado a Devoluciones Bucle equivalente
(mapcar fl 1 ... l n ) coche lista de resultados (bucle para x 1 en l 1 … para x n en l n collect (fx 1 … x n ))
(maplist fl 1 ... l n ) cdr lista de resultados (bucle para x 1 en l 1 … para x n en l n collect (fx 1 … x n ))
(mapcan fl 1 ... l n ) coche concatenación de resultados (bucle para x 1 en l 1 ... para x n en l n nconc (fx 1 ... x n ))
(mapcon fl 1 ... l n ) cdr concatenación de resultados (bucle para x 1 en l 1 … para x n en l n nconc (fx 1 … x n ))
(mapc fl 1 … l n ) coche l 1 (bucle para x 1 en l 1 ... para x n en l n do (fx 1 ... x n ) finalmente (retorno l 1 ))
(mapl fl 1 ... l n ) cdr l 1 (bucle para x 1 en l 1 ... para x n en l n do (fx 1 ... x n ) finalmente (retorno l 1 ))

Tenga en cuenta que, en todos los casos, las listas pueden ser de diferentes longitudes, y la aplicación termina cuando se termina la lista más corta.

Hay otras dos funciones de mapas disponibles: map , que se puede aplicar a secuencias (cadenas, vectores, listas), análogo a mapcar , y que puede devolver cualquier tipo de secuencia, especificado como primer argumento, y map-into , análogo a map , pero que modifica destructivamente su primer argumento de secuencia para mantener los resultados de la aplicación de la función.

Ejemplos de MAPCAR

MAPCAR es la función más utilizada de la familia:

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)

Un uso idiomático de mapcar es transponer una matriz representada como una lista de listas:

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 |
;  +---+---+---+               +---+---+---+

Para una explicación, vea esta respuesta .

Ejemplos de 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))

Ejemplos de MAPCAN y 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)

Uno de los usos de MAPCAN es crear una lista de resultados sin valores 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)

Ejemplos de MAPC y 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)


Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow