Fork me on GitHub
#specter
<
2018-03-28
>
axrs12:03:18

Hi all 🙂 Is it possible to transform a collection and update in-place? For a simplified example, say I have a vector of [1 2 3 4 5 ...]. The first iteration happens on index 0 first (`value 1 in this case`) and adds 10 to the value to give 11 and updates the collection [11 2 3 4 5...]. The second iteration happens on index 1 (value 2), but uses an updated collection, i.e. [11 2 3 4 5 ...].

axrs12:03:21

I suppose what I need is a transient transform

nathanmarz17:03:35

@axrs not sure what you mean

nathanmarz17:03:22

you want the entire collection passed to the update function?

axrs22:03:09

hmm. Not quite. using sp/VAL I can get the entire collection. I'm updating a single key for each map in a vector. As the transformation moves through the maps, they use values from a previous map entry to perform a calculation and provide a result. (def col [{:a 1} {:a 5} {:a 9}]) My transformation for each map entry would be 1. Get the previous map value for :a 2. Multiply that by 2 and add 8 3. Add to the current map value for :a 4. persist back into collection

axrs22:03:51

As a rough approximation. The actual calculation for the new value is more involved, but it requires an updated col as the transformation moves through

nathanmarz22:03:53

@axrs that's a perfect use case for zipper navigators

nathanmarz22:03:56

(require '[com.rpl.specter.zipper :as z])
(transform
  [z/VECTOR-ZIP
   z/DOWN
   z/NEXT
   z/NEXT-WALK
   (collect-one z/PREV z/NODE :a)
   z/NODE
   :a]
  (fn [v curr]
    (+ curr (* 2 v) 8))
  col)

axrs22:03:11

Ooo. That's a lot to consume, but looks like it would do the job. Thanks @nathanmarz, I'll have a look into it