add set-elem navigator and change semantics of map-key to only navigate if the key exists (for consistency with set-elem)

This commit is contained in:
nathanmarz 2017-05-07 19:36:50 -04:00
parent 82314f50ba
commit 2dd6432c69
3 changed files with 35 additions and 8 deletions

View file

@ -2,6 +2,7 @@
* Added `pred=`, `pred<`, `pred>`, `pred<=`, `pred>=` for filtering using common comparisons
* Add `map-key` navigator
* Add `set-elem` navigator
## 1.0.1

View file

@ -869,17 +869,37 @@
structure)))))
(defrichnav
^{:doc "Navigates to the given key in the map (not to the value). Navigates regardless
of whether the key currently exists in the map. For transforms, will assoc nil
value if key doesn't currently exist in map."}
^{:doc "Navigates to the given key in the map (not to the value). Navigates only if the
key currently exists in the map."}
map-key
[key]
(select* [this vals structure next-fn]
(next-fn vals key))
(if (contains? structure key)
(next-fn vals key)
NONE
))
(transform* [this vals structure next-fn]
(let [newkey (next-fn vals key)
oldval (get structure key)]
(-> structure (dissoc key) (assoc newkey oldval))
(if (contains? structure key)
(let [newkey (next-fn vals key)
oldval (get structure key)]
(-> structure (dissoc key) (assoc newkey oldval))
)
structure
)))
(defrichnav
^{:doc "Navigates to the given element in the set only if it exists in the set."}
set-elem
[elem]
(select* [this vals structure next-fn]
(if (contains? structure elem)
(next-fn vals elem)
NONE
))
(transform* [this vals structure next-fn]
(if (contains? structure elem)
(-> structure (disj elem) (conj (next-fn vals elem)))
structure
)))
(def ^{:doc "Navigate to the specified keys one after another. If navigate to NONE,

View file

@ -1528,11 +1528,17 @@
))
(deftest map-key-test
(is (= {:b nil :c 3} (setval (s/map-key :a) :b {:c 3})))
(is (= {:c 3} (setval (s/map-key :a) :b {:c 3})))
(is (= {:b 2} (setval (s/map-key :a) :b {:a 2})))
(is (= {:b 2} (setval (s/map-key :a) :b {:a 2 :b 1})))
)
(deftest set-elem-test
(is (= #{:b :d} (setval (s/set-elem :a) :x #{:b :d})))
(is (= #{:x :a} (setval (s/set-elem :b) :x #{:b :a})))
(is (= #{:a} (setval (s/set-elem :b) :a #{:b :a})))
)
#?(:clj
(do
(defprotocolpath FooPP)