Suche…


Überblick

In Common Lisp steht eine Reihe von Mapping-Funktionen auf hoher Ebene zur Verfügung, um eine Funktion auf die Elemente einer oder mehrerer Listen anzuwenden. Sie unterscheiden sich in der Art und Weise, wie die Funktion auf die Listen angewendet wird und wie das Endergebnis erhalten wird. Die folgende Tabelle fasst die Unterschiede zusammen und zeigt für jedes von ihnen das entsprechende LOOP-Formular. f ist die anzuwendende Funktion, die eine Anzahl von Argumenten haben muss, die der Anzahl der Listen entspricht. "Auf Auto angewendet" bedeutet, dass es wiederum auf die Elemente der Listen angewendet wird. "Auf CDR angewendet" bedeutet, dass es wiederum auf die Listen, ihre CDR, ihre CDdr, usw. angewendet wird. Die Spalte „Returns“ zeigt an, ob das globale Ergebnis durch Auflisten der Ergebnisse, Verketten (dh es müssen Listen sein müssen!) oder einfach für Nebeneffekte erhalten werden (und in diesem Fall die erste Liste zurückgegeben wird).

Funktion Angewendet Kehrt zurück Gleichwertiges LOOP
(Mapcar fl 1 … l n ) Auto Liste der Ergebnisse (Schleife für x 1 in l 1 … für x n in l n sammeln (fx 1 … x n ))
(Kartenliste fl 1 … l n ) cdr Liste der Ergebnisse (Schleife für x 1 auf l 1 … für x n auf l n sammeln (fx 1 … x n ))
(mapcan fl 1 … l n ) Auto Verkettung der Ergebnisse (Schleife für x 1 in l 1 … für x n in l n nconc (fx 1 … x n ))
(mapcon fl 1 … l n ) cdr Verkettung der Ergebnisse (Schleife für x 1 auf l 1 … für x n auf l n nconc (fx 1 … x n ))
(mapc fl 1 … l n ) Auto l 1 (Schleife für x 1 in l 1 … für x n in l n do (fx 1 … x n ) schließlich (return l 1 ))
(mapl fl 1 … l n ) cdr l 1 (Schleife für x 1 auf l 1 … für x n auf l n do (fx 1 … x n ) schließlich (return l 1 ))

Beachten Sie, dass die Listen in allen Fällen unterschiedlich lang sein können und die Anwendung beendet wird, wenn die kürzeste Liste beendet wird.

Weitere Kartenfunktionen stehen zur Verfügung: map , das auf Sequenzen (Strings, Vektoren, Listen) analog zu mapcar kann und jede Art von Sequenz zurückgeben kann, die als erstes Argument angegeben ist, und map-into analog zu map Dies ändert jedoch destruktiv sein erstes Sequenzargument, um die Ergebnisse der Anwendung der Funktion beizubehalten.

Beispiele für MAPCAR

MAPCAR ist die am häufigsten verwendete Funktion der Familie:

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)

Eine idiomatische Verwendung von mapcar ist die Transponierung einer Matrix, die als mapcar wird:

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

Eine Erklärung finden Sie in dieser Antwort .

Beispiele für 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))

Beispiele für MAPCAN und 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 wird unter anderem dazu verwendet, eine Ergebnisliste ohne NIL-Werte zu erstellen:

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)

Beispiele für MAPC und 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
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow