Skip to content

Commit

Permalink
redplanetlabs#235 - submap sub map should maintain properties of pa…
Browse files Browse the repository at this point in the history
…rent map

WORK IN PROGRESS

TODO: check if additional map types need support, implement and test submap! nav

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 Aug 21, 2020
1 parent edd7429 commit 1de62b7
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 3 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/get-submap structure m-keys)))

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

(defn- maintain-sorted-submap [structure m-keys]
(let [ordered-select-keys (fn [map keyseq]
(let [s (set keyseq)]
(into (empty map) (select-keys map s))))]
(ordered-select-keys structure m-keys)))

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

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

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

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

#?(:clj clojure.lang.PersistentTreeMap :cljs cljs.core/PersistentTreeMap)
#?(:clj
(get-submap [structure m-keys]
(maintain-sorted-submap structure m-keys)))
)
1 change: 1 addition & 0 deletions src/clj/com/rpl/specter/protocols.cljc
Expand Up @@ -25,3 +25,4 @@

(defprotocol ImplicitNav
(implicit-nav [obj]))

6 changes: 5 additions & 1 deletion test/com/rpl/specter/core_test.cljc
Expand Up @@ -623,7 +623,11 @@
(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}})))
(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 1de62b7

Please sign in to comment.