Qu'est-ce que vous avez besoin est une combinaison de
Quelque chose comme ceci:
(defun array-map (function array
&optional (retval (make-array (array-dimensions array))))
"Apply FUNCTION to each element of ARRAY.
Return a new array, or write into the optional 3rd argument."
(dotimes (i (array-total-size array) retval)
(setf (row-major-aref retval i)
(funcall function (row-major-aref array i)))))
Exemple:
(defparameter a (make-array '(2 3) :initial-contents '((1 2 3) (4 5 6))))
a
==> #2A((1 2 3) (4 5 6))
(array-map #'sqrt a)
==> #2A((1 1.4142135 1.7320508) (2 2.236068 2.4494898))
a ; does not change!
==> #2A((1 2 3) (4 5 6))
Vous pouvez également utiliser array-map
similaire à map-into
:
(array-map #'1+ a a)
==> #2A((2 3 4) (5 6 7))
a ; modified, no new storage is allocated
==> #2A((2 3 4) (5 6 7))
Remarque que array-map
fonctionnera sur n'importe quelle dimension de tableau, des vecteurs aux matrices à 10d & c.
exercice: mettre en œuvre array-multi-map
acceptant une fonction d'un nombre quelconque d'argument et un nombre quelconque de rangées, de sorte que
(array-multi-map #'+ #A((1 2 3) (4 5 6)) #A((11 22 33) (44 55 66)))
==> #A((12 24 36) (48 60 72))
PS. L'ensemble CLHS Chapter 15 Arrays ou CLtL2 Chapter 17 Arrays mérite d'être étudié.
Il peut être utile de laisser l'utilisateur spécifier le type d'élément pour le nouveau tableau. – jkiiski
@jkiiski: J'y ai pensé, mais j'ai décidé contre. Si l'utilisateur veut ce niveau de contrôle, il peut passer 'retval'. En déduire le type de tableau à partir du type de tableau d'argument peut empêcher l'exemple 'sqrt' de fonctionner parce que le tableau d'entrée peut être spécialisé en entiers. – sds
C'est génial. Je vous remercie. J'aime que c'est très simple et facilement réalisable malgré des fonctions plus compliquées. – RufLife