add compact navigator

This commit is contained in:
nathanmarz 2017-12-21 13:15:22 -05:00
parent 632e710b07
commit 6a5054feea
3 changed files with 24 additions and 0 deletions

View file

@ -2,6 +2,7 @@
* Add `vtransform` variant of `transform` that takes in collected values as a vector in the first argument rather than spliced into argument list.
* Add `vterminal` that takes in collected vals as vector in first argument rather than spliced into argument list.
* Add `compact` navigator. After each step of navigation of its subpath, `compact` removes the collection if it's empty.
* Change `terminal` to be a no-op on select codepath
## 1.0.5

View file

@ -1455,3 +1455,11 @@
(cond-path (pred afn) STAY
coll? [ALL-WITH-META p]
)))
(let [compact* (stay-then-continue (if-path empty? (terminal-val NONE)))]
(defdynamicnav compact
"During transforms, after each step of navigation in subpath check if the
value is empty. If so, remove that value by setting it to NONE."
[& path]
(interleave (repeat (count path) compact*) path)
))

View file

@ -1662,6 +1662,21 @@
(is (= {:a 6} (vtransform [:a (s/putval 2) (s/putval 3)] (fn [vs v] (+ v (reduce + vs))) {:a 1})))
)
(deftest compact-test
(is (= {} (setval [:a (s/compact :b :c)] s/NONE {:a {:b {:c 1}}})))
(is (= {:a {:d 2}} (setval [:a (s/compact :b :c)] s/NONE {:a {:b {:c 1} :d 2}})))
(let [TREE-VALUES (recursive-path [] p (s/if-path vector? [(s/compact s/ALL) p] s/STAY))
tree [1 [2 3] [4 [[5] [[6]]]]]]
(is (= [2 4 6] (select [TREE-VALUES even?] tree)))
(is (= [1 [3] [[[5]]]] (setval [TREE-VALUES even?] s/NONE tree)))
)
(is (= [{:a [{:c 1}]}]
(setval [s/ALL (s/compact :a s/ALL :b)]
s/NONE
[{:a [{:b 3}]}
{:a [{:b 2 :c 1}]}])))
)
#?(:clj
(do
(defprotocolpath FooPP)