Sök…


Översikt

En uppsättning mappningsfunktionerhög nivå finns i Common Lisp för att tillämpa en funktion på elementen i en eller flera listor. De skiljer sig åt på vilket sätt funktionen tillämpas på listorna och hur det slutliga resultatet erhålls. Följande tabell sammanfattar skillnaderna och visar för var och en av dem motsvarande LOOP-form. f är den funktion som ska tillämpas, som måste ha ett antal argument lika med antalet listor; "Tillämpas på bil" betyder att det tillämpas i tur och ordning på elementen i listorna, "tillämpas på cdr" betyder att det tillämpas i tur och ordning på listorna, deras cdr, deras cddr osv .; kolumnen "returnerar" visar om det globala resultatet erhålls genom att lista resultaten, sammanfoga dem (så de måste vara listor!) eller helt enkelt användas för biverkningar (och i detta fall returneras den första listan).

Fungera Appliceras på Returer Motsvarande LOOP
(kartbil fl 1 ... l n ) bil lista över resultat (slinga för x 1 i l 1 ... för x n i l n samla (fx 1 ... x n ))
(kartlista fl 1 ... l n ) CDR lista över resultat (slinga för x 1 på l 1 ... för x n på l n samla (fx 1 ... x n ))
(mapcan fl 1 ... l n ) bil sammanlänkning av resultat (slinga för x 1 i l 1 ... för x n i l n nconc (fx 1 ... x n ))
(mapcon fl 1 ... l n ) CDR sammanlänkning av resultat (slinga för x 1 på l 1 ... för x n på l n nconc (fx 1 ... x n ))
(mapc fl 1 ... l n ) bil l 1 (slinga för x 1 i l 1 ... för x n i l n do (fx 1 ... x n ) äntligen (retur l 1 ))
(mapl fl 1 ... l n ) CDR l 1 (slinga för x 1 på l 1 ... för x n på l n do (fx 1 ... x n ) äntligen (retur l 1 ))

Observera att listorna i alla fall kan ha olika längder och applikationen avslutas när den kortaste listan avslutas.

Ytterligare ett par kartfunktioner är tillgängliga: map , som kan tillämpas på sekvenser (strängar, vektorer, listor), analog till mapcar , och som kan returnera alla typer av sekvenser, specificerade som första argument, och map-into , analog till map , men det ändrar destruktivt sitt första sekvensargument för att behålla resultaten av tillämpningen av funktionen.

Exempel på MAPCAR

MAPCAR är familjens mest använda funktion:

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)

En idiomatisk användning av mapcar är att transponera en matris representerad som en lista med listor:

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

För att få en förklaring, se detta svar .

Exempel på 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))

Exempel på MAPCAN och 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)

En av användningarna av MAPCAN är att skapa en resultatlista utan NIL-värden:

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)

Exempel på MAPC och 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
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow