2

我可以vector-add为循环指定一个自定义求和函数(例如,)吗?

我想做这样的事情:

(loop for vec in '((1 2) (3 4)) sum vec)
;=> (4 6)
4

3 回答 3

4

这是个有趣的问题。如果你能做到这一点会很好,但简短的回答是“不”。根据HyperSpec 中的6.1.3 值累积条款

该构造在每次迭代中形成 所提供形式的连续主值sum的累积和。参数var用于累加总和;如果提供了var,则循环不会自动返回最终总和。var参数就像被构造绑定到适当类型的零一样。后续值(包括任何必要的强制转换)就像由函数计算一样。如果使用var,则可以使用type -specvar提供类型with +into 争论; 如果提供了非数字类型,则结果未指定 。如果没有into变量,可选的type-spec 参数适用于保持总和的内部变量。默认类型依赖于实现的;但它必须是number类型 的类型

您的实际用例是这么简单(遍历列表并计算它们的向量和)还是更复杂?如果就这么简单,你可以用reduce. 它看起来更像

(reduce 'vector-add '((1 2) (3 4)))

vector-add您的自定义求和函数在哪里。如果您仍然需要使用loop,您可以使用in和显式获得reduce类似行为。首先,有一个定义,for sum = ... then ...loopfinally (return sum)vector-add

(defun vector-add (x y)
  (mapcar '+ x y))

(vector-add '(1 2) '(3 4))
;=> (4 6)

我们可以做的:

(loop
   for vec in '((1 2) (3 4) (5 6))
   for sum = vec then (vector-add sum vec)
   finally (return sum))
;=> (9 12)
于 2013-09-25T15:04:11.020 回答
3

您可以使用iterate库执行此操作:

(ql:quickload "iterate")

(use-package :iterate)

(defun vector-add (x y) (mapcar '+ x y))

(iter (for i in '((1 2) (3 4))) (reducing i by #'vector-add)) ; (4 6)
于 2013-09-26T08:00:13.203 回答
1

除了对子句使用特殊的求和函数之外,另一种自定义求和的方法for ... = ... then ...是使用sum ... into ...子句:

(loop for (n1 n2) in '((1 2) (3 4))
   sum n1 into s1
   sum n2 into s2
   finally (return (list s1 s2)))
于 2013-09-25T20:12:11.660 回答