diff --git a/src/clj/com/rpl/specter.cljc b/src/clj/com/rpl/specter.cljc index 8d76326..9c2d480 100644 --- a/src/clj/com/rpl/specter.cljc +++ b/src/clj/com/rpl/specter.cljc @@ -1468,3 +1468,24 @@ [& path] (map compact* path) )) + +(defn- map-filter-helper [item-map keys] + (if (empty? keys) + STAY ; base case + (let [key (first keys) value (get item-map key)] + (if-path (i/combine-two-navs (n/keypath* key) (pred= value)) + (map-filter-helper item-map (rest keys))) + ) + )) + +(extend-type #?(:clj clojure.lang.PersistentArrayMap :cljs cljs.core/PersistentArrayMap) + ImplicitNav + (implicit-nav [this] + (map-filter-helper this (keys this)) + )) + +(extend-type #?(:clj clojure.lang.PersistentHashMap :cljs cljs.core/PersistentHashMap) + ImplicitNav + (implicit-nav [this] + (map-filter-helper this (keys this)) + )) diff --git a/test/com/rpl/specter/core_test.cljc b/test/com/rpl/specter/core_test.cljc index 740bf3e..206ae7c 100644 --- a/test/com/rpl/specter/core_test.cljc +++ b/test/com/rpl/specter/core_test.cljc @@ -1694,3 +1694,21 @@ (is (satisfies-protpath? FooPP "a")) (is (not (satisfies-protpath? FooPP 1))) ))) + +(deftest implicit-map-nav-test + (def my-x 100) + (let [ab-map {:a 1 :b 2} + c-map {:k 3 :l 4 :m 5} + abc-map (assoc ab-map :c c-map)] + (for [filter-map [ab-map abc-map {:c c-map} {}]] + ;; all of these cases should select the full map + (is (= [abc-map] (select [filter-map] abc-map))) + ) + (is (= [] (select [{:a -9}] abc-map))) + (let [my-x 100] + (do + ;; test with binding + (is (= [] (select [{:x my-x :y 17}] {:x (+ my-x 1) :y 17}))) + (is (= [{:x 100 :y 17}] (select [{:x my-x :y 17}] {:x 100 :y 17}))) + )) + ))