common-lisp
Mapping-Funktionen über Listen
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)