Skip to content

Map sur une séquence en Common Lisp

Common Lisp propose plusieurs fonctions “map” qui permettent d’appliquer une fonction sur un ensemble de valeurs contenue dans une séquence. Une séquence peut être une chaine de caractères, une liste ou un vecteur. Il y a même une fonction “map” pour les tables de hachages.

“map” est sans doute la plus générique, elle prend un argument qui permet de définir le type de séquence voulue (‘list ou ‘vector), une fonction et une ou plusieurs séquences. La fonction prend autant d’arguments que le nombre de séquences fournies:

CL-USER> (map 'list #'+ '(1 2 3) '(1 2 3) '(1 2 3))
(3 6 9)

Ou encore:

CL-USER> (map 'vector #'identity "Stephane")
#(#\S #\t #\e #\p #\h #\a #\n #\e)

“map-into” applique une fonction sur une séquence et retourne le résultat, elle place également le résultat de façon destructive dans la variable qui lui est passée en argument:

CL-USER> (defvar a '(1 2 3))
A
CL-USER> (map-into a #'1+ a)
(2 3 4)
CL-USER> a
(2 3 4)

“mapcar” fait la même chose que “map”, mais ne travaille qu’avec des listes.

CL-USER> (mapcar #'1+ '(1 2 3))
(2 3 4)
CL-USER>

“mapc” fait la même chose que “mapcar”, mais au lieu de retourner le résultat, cette fonction retourne la liste passée en argument.

CL-USER> (mapc #'1+ '(1 2 3))
(1 2 3)
CL-USER>

“maplist” n’applique pas la fonction à chaque élément de la liste, même à la liste en entier d’abord, puis au CDR de la liste, puis au CDR du CDR de la liste … ainsi de suite jusqu’à ce que la liste soit vide.

CL-USER> (maplist #'identity '(1 2 3))
((1 2 3) (2 3) (3))
CL-USER>

“mapl” est le “mapc” de “maplist”. La fonction donnée en argument s’applique sur la liste de la même façon, mais la valeur retournée est celle de la liste passée en argument.

CL-USER> (mapl #'identity '(1 2 3))
(1 2 3)

“mapcan” est similaire à “mapcar”, mais il construit la liste retournée avec la fonction “nconc” plutôt que “list”, ce qui fait que la fonction doit retourner une liste:

CL-USER> (mapcan #'list '(1 2 3) '(1 2 3))
(1 1 2 2 3 3)
CL-USER> (mapcar #'list '(1 2 3) '(1 2 3))
((1 1) (2 2) (3 3))

“maphash” fait la même chose que “mapcar”, mais sur une table de hashage. La fonction passée en argument prend deux argument, un pour la clef et un pour la valeur.

CL-USER> (setq a (make-hash-table))
#<HASH-TABLE :TEST EQL :COUNT 0 {70088A58D3}>
CL-USER> (setf (gethash "one" a) 1)
1 (1 bit, #x1, #o1, #b1)
CL-USER> (maphash #'(lambda (k v) (format t "~A => ~A~%" k v)) a)
one => 1