Map with an accumulator in Clojure?
clojure
Solution
You should look into `reductions`. For this specific case:
(reductions #(+ % (* 2 %2)) 2 (range 2 6))
produces
(2 6 12 20 30)
Problem
I want to map over a sequence in order but want to carry an accumulator value forward, like in a reduce. Example use case: Take a vector and return a running total, each value multiplied by two. ``` (defn map-with-accumulator "Map over input but with an accumulator. func accepts [value accumulator] and returns [new-value new-accumulator]." [func accumulator collection] (if (empty? collection) nil (let [[this-value new-accumulator] (func (first collection) accumulator)] (cons this-value (map-with-accumulator func new-accumulator (rest collection)))))) (defn double-running-sum [value accumulator] [(* 2 (+ value accumulator)) (+ value accumulator)]) ``` Which gives ``` (prn (pr-str (map-with-accumulator double-running-sum 0 [1 2 3 4 5]))) >>> (2 6 12 20 30) ``` Another example to illustrate the generality, print running sum as stars and the original number. A slightly convoluted example, but demonstrates that I need to keep the running accumulator in the map function: ``` (defn stars [n] (apply str (take n (repeat \*)))) (defn stars-sum [value accumulator] [[(stars (+ value accumulator)) value] (+ value accumulator)]) (prn (pr-str (map-with-accumulator stars-sum 0 [1 2 3 4 5]))) >>> (["*" 1] ["***" 2] ["******" 3] ["**********" 4] ["***************" 5]) ``` This works fine, but I would expect this to be a common pattern, and for some kind of `map-with-accumulator` to exist in `core`. Does it?