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 ...]
.
I suppose what I need is a transient transform
@axrs not sure what you mean
you want the entire collection passed to the update function?
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
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
@axrs that's a perfect use case for zipper navigators
(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)
Ooo. That's a lot to consume, but looks like it would do the job. Thanks @nathanmarz, I'll have a look into it
this will be helpful for you https://github.com/nathanmarz/specter/wiki/Using-Specter-With-Zippers