我可以vector-add
为循环指定一个自定义求和函数(例如,)吗?
我想做这样的事情:
(loop for vec in '((1 2) (3 4)) sum vec)
;=> (4 6)
我可以vector-add
为循环指定一个自定义求和函数(例如,)吗?
我想做这样的事情:
(loop for vec in '((1 2) (3 4)) sum vec)
;=> (4 6)
这是个有趣的问题。如果你能做到这一点会很好,但简短的回答是“不”。根据HyperSpec 中的6.1.3 值累积条款:
该构造在每次迭代中形成 所提供形式的连续主值
sum
的累积和。参数var用于累加总和;如果提供了var,则循环不会自动返回最终总和。var参数就像被构造绑定到适当类型的零一样。后续值(包括任何必要的强制转换)就像由函数计算一样。如果使用var,则可以使用type -spec为var提供类型with
+
into
争论; 如果提供了非数字类型,则结果未指定 。如果没有into
变量,可选的type-spec 参数适用于保持总和的内部变量。默认类型是依赖于实现的;但它必须是number类型 的超类型 。
您的实际用例是这么简单(遍历列表并计算它们的向量和)还是更复杂?如果就这么简单,你可以用reduce
. 它看起来更像
(reduce 'vector-add '((1 2) (3 4)))
vector-add
您的自定义求和函数在哪里。如果您仍然需要使用loop
,您可以使用in和显式获得reduce
类似行为。首先,有一个定义,for sum = ... then ...
loop
finally (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)
您可以使用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)
除了对子句使用特殊的求和函数之外,另一种自定义求和的方法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)))