你需要的是
事情是這樣的:
(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)))))
例子:
(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))
您還可以使用array-map
類似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))
注意array-map
將工作在任何陣列維度上,從矢量到矩陣到10d & c。
練習:實施array-multi-map
接受任何數量的參數和任意數量的陣列的功能,從而使
(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。整個CLHS Chapter 15 Arrays或CLtL2 Chapter 17 Arrays值得研究。
來源
2017-07-19 14:30:10
sds
讓用戶指定新數組的元素類型可能會很好。 – jkiiski
@jkiiski:我想過了,但決定反對它。如果用戶想要這個級別的控制,他可以通過'retval'。根據參數數組類型推斷數組類型可能會阻止'sqrt'示例工作,因爲輸入數組可能專用於整數。 – sds
這太好了。謝謝。我喜歡它儘管功能更復雜,但它非常簡單易於實現。 – RufLife