2017-07-19 44 views
1

所有的地圖功能,如mapcar,mapcan, mapc等都需要列表作爲它們的輸入。我正在處理二維數組,並且在給定通常較大的尺寸(有時爲50,000 x 1,000)的情況下,寧願不要混淆我的數組的排名。尋找一種通過2D Lisp陣列映射功能的方法

我需要一種方法來將像(log n)這樣的函數應用到二維數組中的每個元素,並生成一個結果二維數組。

任何幫助或方向是非常感謝。

在AllegroCL(Common Lisp的)工作

回答

5

你需要的是

事情是這樣的:

(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 ArraysCLtL2 Chapter 17 Arrays值得研究。

+0

讓用戶指定新數組的元素類型可能會很好。 – jkiiski

+0

@jkiiski:我想過了,但決定反對它。如果用戶想要這個級別的控制,他可以通過'retval'。根據參數數組類型推斷數組類型可能會阻止'sqrt'示例工作,因爲輸入數組可能專用於整數。 – sds

+0

這太好了。謝謝。我喜歡它儘管功能更復雜,但它非常簡單易於實現。 – RufLife