diff --git a/CHANGES.md b/CHANGES.md index c64a822..3b702b1 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,6 +1,7 @@ ## 1.0.2-SNAPSHOT * Added `pred=`, `pred<`, `pred>`, `pred<=`, `pred>=` for filtering using common comparisons +* Add `map-key` navigator ## 1.0.1 diff --git a/src/clj/com/rpl/specter.cljc b/src/clj/com/rpl/specter.cljc index 7c5f3d6..eb4d71e 100644 --- a/src/clj/com/rpl/specter.cljc +++ b/src/clj/com/rpl/specter.cljc @@ -868,6 +868,20 @@ ))) 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."} + map-key + [key] + (select* [this vals structure next-fn] + (next-fn vals key)) + (transform* [this vals structure next-fn] + (let [newkey (next-fn vals key) + oldval (get structure key)] + (-> structure (dissoc key) (assoc newkey oldval)) + ))) + (def ^{:doc "Navigate to the specified keys one after another. If navigate to NONE, that element is removed from the map or vector."} keypath diff --git a/test/com/rpl/specter/core_test.cljc b/test/com/rpl/specter/core_test.cljc index 1b6de84..eaa0278 100644 --- a/test/com/rpl/specter/core_test.cljc +++ b/test/com/rpl/specter/core_test.cljc @@ -1527,6 +1527,11 @@ (is (= [3 4] (select [s/ALL (s/pred>= 3)] data))) )) +(deftest map-key-test + (is (= {:b nil :c 3} (setval (s/map-key :a) :b {:c 3}))) + (is (= {:b 2} (setval (s/map-key :a) :b {:a 2}))) + ) + #?(:clj (do (defprotocolpath FooPP)