I have a data set that looks like this
[{1 "a"} {2 "b"} {3 "c"}]
I want to transform it into a cummulative map that looks like
{1 "a" 3 "b" 6 "c"}
I think my current approach is long winded. So far I have come up with
(reduce
(fn [sum item]
(assoc sum (+ (reduce + (keys sum))
(key (first item)))
(val (first item))))
split-map)
but the addition on the keys is incorrect. Does anyone know how I can improve on this?
Here is a possible implementation of the computation and it makes extensive use of Clojure sequence functions:
(defn cumul-pairs [data]
(zipmap (rest (reductions ((map (comp key first)) +) 0 data))
(map (comp val first) data)))
(cumul-pairs [{1 "a"} {2 "b"} {3 "c"}])
;; => {1 "a", 3 "b", 6 "c"}
In this code, the expression (rest (reductions ((map (comp first keys)) +) 0 data))
computes the keys of the resulting map and the expression (map (comp first vals) data)
computes the values. Then we combine them with zipmap. The function reductions works just like reduce but returns a sequence of all intermediate results instead of just the last one. The curious looking subexpression ((map (comp first keys)) +)
is the reducing function, where we use a mapping transducer to construct a reducing function from the + reducing function that will map the input value before adding it.