implemented NONE removal for keypath, must, MAP-VALS (except PersistentArrayMap), ALL (except lists and PersistentArrayMap)

This commit is contained in:
nathanmarz 2017-01-08 12:52:54 -05:00
parent 4774c2e30a
commit fca11410b4

View file

@ -64,8 +64,10 @@
(defn- non-transient-map-all-transform [structure next-fn empty-map] (defn- non-transient-map-all-transform [structure next-fn empty-map]
(reduce-kv (reduce-kv
(fn [m k v] (fn [m k v]
(let [[newk newv] (next-fn [k v])] (let [newkv (next-fn [k v])]
(assoc m newk newv))) (if (identical? newkv i/NONE)
m
(assoc m (nth newkv 0) (nth newkv 1)))))
empty-map empty-map
structure)) structure))
@ -88,7 +90,10 @@
#?(:clj clojure.lang.PersistentVector :cljs cljs.core/PersistentVector) #?(:clj clojure.lang.PersistentVector :cljs cljs.core/PersistentVector)
(all-transform [structure next-fn] (all-transform [structure next-fn]
(mapv next-fn structure)) (into []
(comp (map next-fn)
(filter #(-> % (identical? i/NONE) not)))
structure))
#?(:clj clojure.lang.PersistentArrayMap) #?(:clj clojure.lang.PersistentArrayMap)
#?(:clj #?(:clj
@ -96,6 +101,9 @@
(let [k-it (.keyIterator structure) (let [k-it (.keyIterator structure)
v-it (.valIterator structure) v-it (.valIterator structure)
array (i/fast-object-array (* 2 (.count structure)))] array (i/fast-object-array (* 2 (.count structure)))]
;;TODO: how to handle NONE here...?
;;needs to size the array appropriately...
;;need to use the same strategy for MAP-VALS
(loop [i 0] (loop [i 0]
(if (.hasNext k-it) (if (.hasNext k-it)
(let [k (.next k-it) (let [k (.next k-it)
@ -123,8 +131,10 @@
(persistent! (persistent!
(reduce-kv (reduce-kv
(fn [m k v] (fn [m k v]
(let [[newk newv] (next-fn [k v])] (let [newkv (next-fn [k v])]
(assoc! m newk newv))) (if (identical? newkv i/NONE)
m
(assoc! m (nth newkv 0) (nth newkv 1)))))
(transient (transient
#?(:clj clojure.lang.PersistentHashMap/EMPTY :cljs cljs.core.PersistentHashMap.EMPTY)) #?(:clj clojure.lang.PersistentHashMap/EMPTY :cljs cljs.core.PersistentHashMap.EMPTY))
@ -139,12 +149,14 @@
(let [empty-structure (empty structure)] (let [empty-structure (empty structure)]
(cond (and (list? empty-structure) (not (queue? empty-structure))) (cond (and (list? empty-structure) (not (queue? empty-structure)))
;; this is done to maintain order, otherwise lists get reversed ;; this is done to maintain order, otherwise lists get reversed
;;TODO: need to handle NONE here
(doall (map next-fn structure)) (doall (map next-fn structure))
(map? structure) (map? structure)
;; reduce-kv is much faster than doing r/map through call to (into ...) ;; reduce-kv is much faster than doing r/map through call to (into ...)
(reduce-kv (reduce-kv
(fn [m k v] (fn [m k v]
;;TODO: need to handle NONE here
(let [[newk newv] (next-fn [k v])] (let [[newk newv] (next-fn [k v])]
(assoc m newk newv))) (assoc m newk newv)))
@ -153,12 +165,14 @@
:else :else
;;TODO: need to handle NONE here
(->> structure (r/map next-fn) (into empty-structure)))))) (->> structure (r/map next-fn) (into empty-structure))))))
#?(:cljs default) #?(:cljs default)
#?(:cljs #?(:cljs
(all-transform [structure next-fn] (all-transform [structure next-fn]
;;TODO: need to handle NONE here
(let [empty-structure (empty structure)] (let [empty-structure (empty structure)]
(if (and (list? empty-structure) (not (queue? empty-structure))) (if (and (list? empty-structure) (not (queue? empty-structure)))
;; this is done to maintain order, otherwise lists get reversed ;; this is done to maintain order, otherwise lists get reversed
@ -173,7 +187,10 @@
(defn map-vals-non-transient-transform [structure empty-map next-fn] (defn map-vals-non-transient-transform [structure empty-map next-fn]
(reduce-kv (reduce-kv
(fn [m k v] (fn [m k v]
(assoc m k (next-fn v))) (let [newv (next-fn v)]
(if (identical? newv i/NONE)
m
(assoc m k newv))))
empty-map empty-map
structure)) structure))
@ -189,6 +206,7 @@
(let [k-it (.keyIterator structure) (let [k-it (.keyIterator structure)
v-it (.valIterator structure) v-it (.valIterator structure)
array (i/fast-object-array (* 2 (.count structure)))] array (i/fast-object-array (* 2 (.count structure)))]
;;TODO: Need to handle NONE here just like it's handled in all-transform
(loop [i 0] (loop [i 0]
(if (.hasNext k-it) (if (.hasNext k-it)
(let [k (.next k-it) (let [k (.next k-it)
@ -216,7 +234,10 @@
(persistent! (persistent!
(reduce-kv (reduce-kv
(fn [m k v] (fn [m k v]
(assoc! m k (next-fn v))) (let [newv (next-fn v)]
(if (identical? newv i/NONE)
m
(assoc! m k newv))))
(transient (transient
#?(:clj clojure.lang.PersistentHashMap/EMPTY :cljs cljs.core.PersistentHashMap.EMPTY)) #?(:clj clojure.lang.PersistentHashMap/EMPTY :cljs cljs.core.PersistentHashMap.EMPTY))
@ -227,7 +248,10 @@
(map-vals-transform [structure next-fn] (map-vals-transform [structure next-fn]
(reduce-kv (reduce-kv
(fn [m k v] (fn [m k v]
(assoc m k (next-fn v))) (let [newv (next-fn v)]
(if (identical? newv i/NONE)
m
(assoc m k newv))))
(empty structure) (empty structure)
structure))) structure)))
@ -407,6 +431,13 @@
(walk/walk (partial walk-until pred on-match-fn) identity structure))) (walk/walk (partial walk-until pred on-match-fn) identity structure)))
(defn- do-keypath-transform [vals structure key next-fn]
;;TODO: not right, this doesn't handle sequences
(let [newv (next-fn vals (get structure key))]
(if (identical? newv i/NONE)
(dissoc structure key)
(assoc structure key newv))))
(defrichnav (defrichnav
^{:doc "Navigates to the specified key, navigating to nil if it does not exist."} ^{:doc "Navigates to the specified key, navigating to nil if it does not exist."}
keypath* keypath*
@ -414,7 +445,8 @@
(select* [this vals structure next-fn] (select* [this vals structure next-fn]
(next-fn vals (get structure key))) (next-fn vals (get structure key)))
(transform* [this vals structure next-fn] (transform* [this vals structure next-fn]
(assoc structure key (next-fn vals (get structure key))))) (do-keypath-transform vals structure key next-fn)
))
(defrichnav (defrichnav
@ -427,5 +459,5 @@
i/NONE)) i/NONE))
(transform* [this vals structure next-fn] (transform* [this vals structure next-fn]
(if (contains? structure k) (if (contains? structure k)
(assoc structure k (next-fn vals (get structure k))) (do-keypath-transform vals structure key next-fn)
structure))) structure)))