Skip to content

Commit

Permalink
submap sub map should maintain properties of parent map redplanetla…
Browse files Browse the repository at this point in the history
…bs#235

TODO: figure out how to handle transients (i.e. submap!)

Adding new SubMap protocol to handle the different implementations of key selection (including one that maintains order to be used for sorted-map)

Adding test to ensure order preserved for a large map
  • Loading branch information
jeff303 committed Sep 16, 2020
1 parent edd7429 commit ed2cfc8
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 4 deletions.
4 changes: 2 additions & 2 deletions src/clj/com/rpl/specter.cljc
Expand Up @@ -905,10 +905,10 @@
submap
[m-keys]
(select* [this structure next-fn]
(next-fn (select-keys structure m-keys)))
(next-fn (n/select-submap structure m-keys)))

(transform* [this structure next-fn]
(let [submap (select-keys structure m-keys)
(let [submap (n/select-submap structure m-keys)
newmap (next-fn submap)]
(merge (reduce dissoc structure m-keys)
newmap))))
Expand Down
27 changes: 27 additions & 0 deletions src/clj/com/rpl/specter/navs.cljc
Expand Up @@ -691,3 +691,30 @@
((:end-fn end-fn) structure start)
(end-fn structure)
))

(defn- maintain-sorted-submap [structure m-keys]
(into (empty structure) (select-keys structure m-keys)))

(defprotocol SubMap
(select-submap [structure m-keys]))

(extend-protocol SubMap
nil
(select-submap [structure m-keys] nil)

#?(:clj clojure.lang.PersistentArrayMap :cljs cljs.core/PersistentArrayMap)
(select-submap [structure m-keys]
(maintain-sorted-submap structure m-keys))

#?(:clj clojure.lang.PersistentHashMap :cljs cljs.core/PersistentHashMap)
(select-submap [structure m-keys]
(select-keys structure m-keys))

#?(:clj clojure.lang.PersistentStructMap)
#?(:clj
(select-submap [structure m-keys]
(select-keys structure m-keys)))

#?(:clj clojure.lang.PersistentTreeMap :cljs cljs.core/PersistentTreeMap)
(select-submap [structure m-keys]
(maintain-sorted-submap structure m-keys)))
14 changes: 12 additions & 2 deletions test/com/rpl/specter/core_test.cljc
Expand Up @@ -611,7 +611,8 @@
(= (transform (s/subset s3) identity combined) combined)
(= (setval (s/subset s3) #{} combined) (set/difference combined s2))
(= (setval (s/subset s3) s4 combined) (-> combined (set/difference s2) (set/union s4)))))))

#?(:clj
(defstruct test-struct :x :y :z))

(deftest submap-test
(is (= [{:foo 1}]
Expand All @@ -623,7 +624,16 @@
(is (= {:a {:new 1}
:c {:new 1
:old 1}}
(setval [s/ALL s/LAST (s/submap [])] {:new 1} {:a nil, :c {:old 1}}))))
(setval [s/ALL s/LAST (s/submap [])] {:new 1} {:a nil, :c {:old 1}})))
#?(:clj
; make sure struct-map works
(is (= [{:z 3, :y 2}]
(select (s/submap [:z :y]) (into (struct-map test-struct) {:x 1 :y 2 :z 3})))))
; ensure order is preserved for larger map (i.e. TreeMap)
(let [range50 (range 50)]
(is (= (take-nth 2 range50)
(select [(s/submap (take-nth 2 range50)) s/MAP-KEYS] (apply sorted-map (interleave range50 range50))))))
)

(deftest nil->val-test
(is (= {:a #{:b}}
Expand Down

0 comments on commit ed2cfc8

Please sign in to comment.