我有一个尺寸为'(3 3 2)的数组,如下所示,名称为test-array:
#3A(((0 0) (0 0.1) (0 0.3))
((1 0) (1 0.1) (1 0.3))
((2 0) (2 0.1) (2 0.3)))
请注意,数组中的最内部列表(等级2)是点坐标,因此通常数组将是
#3A(((x0 y0) (x0 y1) (x0 y2))
((x1 y0) (x1 y1) (x1 y2))
((x2 y0) (x2 y1) (x2 y2)))
现在我想使用此数组中的元素来创建一个新数组。
在这个数组的每一行(array-rank:0)上,我想从第一个和第三个xy坐标中减去第二个xy坐标。所以基本上我在参数化形式中寻找的结果是:
#3A(((x0-x0 y1-y0) (x0-x0 y2-y1))
((x1-x1 y1-y0) (x1-x1 y2-y1))
((x2-x2 y1-y0) (x2-x2 y2-y1))
是否有任何简单的直接函数或操作只通过操作初始数组来实现?
由于我不知道对此有任何直接操作,我想到只是将初始数组中的列表作为新数组的:initial-contents
。因此,这种方法的最初目的是获得初始内容列表:
(((x0-x0 y1-y0) (x0-x0 y2-y1))
((x1-x1 y1-y0) (x1-x1 y2-y1))
((x2-x2 y1-y0) (x2-x2 y2-y1))
为了做到这一点,我想到了一个使用dotimes
两次的代码(外部循环的数量是行数,内部循环的数量就是列的数量):
(let ((result-1))
(dotimes (n (array-dimension test-array 0) result-1)
(setq result-1
(append result-1
(let ((result-2))
(dotimes (m (1- (array-dimension test-array 1)) result-2)
(setq result-2
(append result-2
(list (- (aref test-array n (1+ m) 0)
(aref test-array n m 0))
(- (aref test-array n (1+ m) 1)
(aref test-array n m 1)))))))))))
但这有一个问题,也是问题的标题。显然,CL不理解为aref
提供输入的这种“参数化”方式(使用n& m):(aref test-array n m 0)
为什么会出现这样的问题?你能想到在循环中使用aref的任何其他方法,或者使用另一种方法制作:initial-contents列表吗?
请注意,这是我实际问题的一个相对简单的形式,因为我所拥有的实际初始数组的维度为(21 16 2),所有x y坐标彼此不同。
答案真的很感激......
答案 0 :(得分:3)
正如我在评论中注意到的那样,该函数返回其参数
增加1是1+
,而不是+1
(这不是一个函数名,而是一个
常数1
)。
我认为没有必要在这里构建:initial-contents
,因为它没有
比构造目标数组并填充它更容易
在一个循环中作为一个单独的步骤。我就是这样做的:
(defparameter *test-array*
#3A(((0 0) (0 0.1) (0 0.3))
((1 0) (1 0.1) (1 0.3))
((2 0) (2 0.1) (2 0.3))))
(destructuring-bind (rows cols axes) (array-dimensions *test-array*)
(let ((result (make-array
(list rows (1- cols) axes)
:element-type (array-element-type *test-array*))))
(dotimes (row rows result)
(dotimes (col (1- cols))
(dotimes (axis axes)
(setf (aref result row col axis)
(- (aref *test-array* row (1+ col) axis)
(aref *test-array* row col axis))))))))
我决定让这个例子尽可能简单。替代 解决方案是可能的,例利用向前移动的向量 数组(这就是你如何使用多维数组 使用序列函数)。我更喜欢简单的方法 此任务,如果不是更复杂的情况。