我可以爲循環指定自定義求和功能(例如,vector-add
)嗎?可以cl:循環使用自定義總和功能?
我想要做這樣的事情:
(loop for vec in '((1 2) (3 4)) sum vec)
;=> (4 6)
我可以爲循環指定自定義求和功能(例如,vector-add
)嗎?可以cl:循環使用自定義總和功能?
我想要做這樣的事情:
(loop for vec in '((1 2) (3 4)) sum vec)
;=> (4 6)
這是一個有趣的問題。這將是很好,如果你能做到這一點,但簡短的回答是根據6.1.3 Value Accumulation Clauses從HyperSpec「無」:
的
sum
結構形成連續一次值的累積和所提供的的 在每次迭代中形成。參數var是 用來累加和;如果提供變量,則loop不會自動返回 的最終和。 var自變量被綁定,如果被 構造with
限制爲適當類型的零。隨後的值 (包括任何必要的強制)計算好像通過函數+
。如果into
變種被使用時,型可以VAR與型規格參數被供給;如果提供非數字型 型號,則後果不明確。如果沒有into
變量,則可選的type-spec 參數適用於保留總和的內部變量。 默認類型是實現依賴;但它必須是超類型 的類型號碼。
您的實際使用案例很簡單(循環列表並計算它們的向量和)還是更復雜?如果是這樣簡單,你可以用reduce
做你想做的。它看起來更不像
(reduce 'vector-add '((1 2) (3 4)))
其中vector-add
是您的自定義求和功能。如果您仍然需要使用loop
,則可以使用for sum = ... then ...
中的for sum = ... then ...
以及明確的finally (return sum)
獲得類似reduce
的行爲。首先,隨着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)
另一種方式來定製除了使用特殊的求和函數與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)))
這是'vector-add'的解決方案,但不能推廣到其他非算術運算。 – SaltyEgg
您可以使用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)
我已經在做減少的事情。即將到來的是整個清單必須先收集然後再收集。 – SaltyEgg
好吧,用問題中的代碼,整個列表已經收集完畢。你能詳細說明一下這個例子嗎? (但是_謝謝你提供了一個簡單的例子,當人們粘貼一個「Wall-of-Code」時會感到沮喪)。循環是否也負責生成單獨的矢量? –
@SaltyEgg我已經更新了答案,以包含'loop'如何以'reduce'方式使用的例子。如果你使用'loop'來生成單獨的加數,那麼你可以使用'for sum = x then(vector-add sum x)'來累加和,但是你也需要明確地'返回'它在結束。 –