基于-recur
的版本非常好,可能是最快的解决方案之一,但如果它要在更大的向量上运行,您可能希望使用瞬变。
作为一种可能的替代方法,我建议使用reduce
它来处理循环,将输入向量作为累加器的初始值传入,并通过range
step 参数提供简化的序列。
(defn step-do [start step v]
(reduce (fn [v i]
(assoc v i (* 10 (nth v i))))
v
(range start (count v) step)))
来自 REPL:
(def xs (vec (range 32)))
(step-do 1 2 xs)
;= [0 10 2 30 4 50 6 70 8 90 10 110 12 130 14 150 16 170 18 190 20 210 22 230 24 250 26 270 28 290 30 310]
This has the benefit of clearly separating the selection of indices at which the transformation is to be applied (here handled by range
; a more involved seq producer could be used if desired) and the transformation itself (captured by the function passed to reduce
; a generalized step-do
could accept a a transformation function as an argument, rather than hardwire multiply-by-10).
Additionally, it should be quite performant (and since reduce
is quite central to Clojure's model of data handling, it's likely to keep improving in future releases). Of course here too transients could be used to speed things up.