added srange, srange-dyamic, START, and END dynamic paths to manipulate parts of a sequence by index

This commit is contained in:
Nathan Marz 2015-04-14 23:49:32 -04:00
parent 4b7682f20b
commit ffd6464d54
3 changed files with 55 additions and 0 deletions

View file

@ -86,6 +86,14 @@
(def FIRST (->FirstStructurePath)) (def FIRST (->FirstStructurePath))
(defn srange-dynamic [start-fn end-fn] (->SRangePath start-fn end-fn))
(defn srange [start end] (srange-dynamic (fn [_] start) (fn [_] end)))
(def START (srange 0 0))
(def END (srange-dynamic count count))
(defn walker [afn] (->WalkerStructurePath afn)) (defn walker [afn] (->WalkerStructurePath afn))
(defn codewalker [afn] (->CodeWalkerStructurePath afn)) (defn codewalker [afn] (->CodeWalkerStructurePath afn))

View file

@ -145,6 +145,7 @@
(let [empty-structure (empty structure) (let [empty-structure (empty structure)
pfn (partial next-fn vals)] pfn (partial next-fn vals)]
(if (list? empty-structure) (if (list? empty-structure)
;; this is done to maintain order, otherwise lists get reversed
(doall (map pfn structure)) (doall (map pfn structure))
(->> structure (r/map pfn) (into empty-structure)) (->> structure (r/map pfn) (into empty-structure))
)))) ))))
@ -217,3 +218,23 @@
(selector-vals* sel-fn selector vals structure next-fn)) (selector-vals* sel-fn selector vals structure next-fn))
(update* [this vals structure next-fn] (update* [this vals structure next-fn]
(selector-vals* sel-fn selector vals structure next-fn))) (selector-vals* sel-fn selector vals structure next-fn)))
(deftype SRangePath [start-fn end-fn]
StructurePath
(select* [this vals structure next-fn]
(let [start (start-fn structure)
end (end-fn structure)]
(next-fn vals (-> structure vec (subvec start end)))
))
(update* [this vals structure next-fn]
(let [start (start-fn structure)
end (end-fn structure)
structurev (vec structure)
newpart (next-fn vals (-> structurev (subvec start end)))
res (concat (subvec structurev 0 start)
newpart
(subvec structurev end (count structure)))]
(if (vector? structure)
(vec res)
res
))))

View file

@ -180,6 +180,32 @@
[res user-ret] [res user-ret]
)))) ))))
(defspec srange-extremes-test
(for-all+
[v (gen/vector gen/int)
v2 (gen/vector gen/int)]
(let [b (setval START v2 v)
e (setval END v2 v)]
(and (= b (concat v2 v))
(= e (concat v v2)))
)))
(defspec srange-test
(for-all+
[v (gen/vector gen/int)
b (gen/elements (-> v count inc range))
e (gen/elements (range b (-> v count inc)))
]
(let [sv (subvec v b e)
predcount (fn [pred v] (->> v (filter pred) count))
even-count (partial predcount even?)
odd-count (partial predcount odd?)
b (update (srange b e) (fn [r] (filter odd? r)) v)]
(and (= (odd-count v) (odd-count b))
(= (+ (even-count b) (even-count sv))
(even-count v)))
)))
(deftest structure-path-directly-test (deftest structure-path-directly-test
(is (= 3 (select-one :b {:a 1 :b 3}))) (is (= 3 (select-one :b {:a 1 :b 3})))
(is (= 5 (select-one (comp-structure-paths :a :b) {:a {:b 5}}))) (is (= 5 (select-one (comp-structure-paths :a :b) {:a {:b 5}})))