specter

Latest version: 1.1.3
axrs 2018-03-28T12:14:18.000092Z

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 ...].

axrs 2018-03-28T12:34:21.000491Z

I suppose what I need is a transient transform

nathanmarz 2018-03-28T17:24:35.000414Z

@axrs not sure what you mean

nathanmarz 2018-03-28T17:25:22.000002Z

you want the entire collection passed to the update function?

axrs 2018-03-28T22:12:09.000201Z

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

axrs 2018-03-28T22:14:51.000016Z

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

nathanmarz 2018-03-28T22:29:53.000120Z

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

nathanmarz 2018-03-28T22:29:56.000453Z

(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)

axrs 2018-03-28T22:34:11.000171Z

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

nathanmarz 2018-03-28T22:36:03.000134Z

this will be helpful for you https://github.com/nathanmarz/specter/wiki/Using-Specter-With-Zippers