specter

nathanmarz 2023-05-29T19:17:40.820139Z

@itai that's just this:

(let [sum (reduce + (traverse [:vals ALL :v] data))]
  (transform [:vals ALL (collect-one :v) :k] (fn [v _] (/ v sum)) data))

itaied 2023-05-30T08:36:10.941349Z

Thanks for you response, but please note that the computation of :k i based on the current :v and the sum of all previous :v 's. In your example, the result is:

{:vals [{:v 1 :k (/ 1 1111)} {:v 10 :k (/ 10 1111)} {:v 100 :k (/ 100 1111)} {:v 1000 :k (/ 1000 1111)}]}

nathanmarz 2023-05-30T19:16:06.343249Z

ah I see

nathanmarz 2023-05-30T19:16:40.930759Z

it's doable with zipper navigators and a recursive-path but it's probably easier just to do a reduce of some sort

itaied 2023-05-31T07:16:38.584769Z

I just implemented mapAccum

(defn map-accum [f init-coll coll]
  (loop [acc init-coll
         result []
         remaining-coll coll]
    (if (empty? remaining-coll)
      result
      (let [[new-acc new-elem] (f acc (first remaining-coll))]
        (recur new-acc (conj result new-elem) (rest remaining-coll))))))