Added continuous-subseqs navigator
This commit is contained in:
parent
009a9c93f6
commit
e2e8fa091e
4 changed files with 63 additions and 0 deletions
|
|
@ -7,9 +7,11 @@
|
|||
* BREAKING CHANGE: `path` renamed to `nav`
|
||||
* BREAKING CHANGE: `fixed-pathed-path` and `variable-pathed-path` renamed to `fixed-pathed-nav` and `variabled-pathed-nav`
|
||||
* Added `must` navigator to navigate to a key if and only if it exists in the structure
|
||||
* Added `continous-subseqs` navigator
|
||||
* Added `ATOM` navigator (thanks @rakeshp)
|
||||
* Added "navigator constructors" that can be defined via `defnavconstructor`. These allow defining a flexible function to parameterize a defnav, and the function integrates with inline caching for high performance.
|
||||
|
||||
|
||||
## 0.10.0
|
||||
* Make codebase bootstrap cljs compatible
|
||||
* Remove usage of reducers in cljs version in favor of transducers (thanks @StephenRudolph)
|
||||
|
|
|
|||
|
|
@ -181,6 +181,24 @@
|
|||
(i/srange-transform structure start end next-fn)
|
||||
))
|
||||
|
||||
(defnav
|
||||
^{:doc "Navigates to every continuous subsequence of elements matching `pred`"}
|
||||
continuous-subseqs
|
||||
[pred]
|
||||
(select* [this structure next-fn]
|
||||
(doall
|
||||
(mapcat
|
||||
(fn [[s e]] (i/srange-select structure s e next-fn))
|
||||
(i/matching-ranges structure pred)
|
||||
)))
|
||||
(transform* [this structure next-fn]
|
||||
(reduce
|
||||
(fn [structure [s e]]
|
||||
(i/srange-transform structure s e next-fn))
|
||||
structure
|
||||
(reverse (i/matching-ranges structure pred))
|
||||
)))
|
||||
|
||||
(def BEGINNING (srange 0 0))
|
||||
|
||||
(def END (srange-dynamic count count))
|
||||
|
|
|
|||
|
|
@ -575,6 +575,27 @@
|
|||
res
|
||||
)))
|
||||
|
||||
(defn- matching-indices [aseq p]
|
||||
(keep-indexed (fn [i e] (if (p e) i)) aseq))
|
||||
|
||||
(defn matching-ranges [aseq p]
|
||||
(first
|
||||
(reduce
|
||||
(fn [[ranges curr-start curr-last :as curr] i]
|
||||
(cond
|
||||
(nil? curr-start)
|
||||
[ranges i i]
|
||||
|
||||
(= i (inc curr-last))
|
||||
[ranges curr-start i]
|
||||
|
||||
:else
|
||||
[(conj ranges [curr-start (inc curr-last)]) i i]
|
||||
))
|
||||
[[] nil nil]
|
||||
(concat (matching-indices aseq p) [-1])
|
||||
)))
|
||||
|
||||
(extend-protocol p/Navigator
|
||||
nil
|
||||
(select* [this structure next-fn]
|
||||
|
|
|
|||
|
|
@ -969,3 +969,25 @@
|
|||
:a
|
||||
))))
|
||||
)
|
||||
|
||||
(defspec continuous-subseqs-filter-equivalence
|
||||
(for-all+
|
||||
[aseq (gen/vector (gen/elements [1 2 3 :a :b :c 4 5 :d :e]))
|
||||
pred (gen/elements [keyword? number?])]
|
||||
(= (setval (s/continuous-subseqs pred) nil aseq)
|
||||
(filter (complement pred) aseq))
|
||||
))
|
||||
|
||||
(deftest continuous-subseqs-test
|
||||
(is (= [1 "ab" 2 3 "c" 4 "def"]
|
||||
(transform
|
||||
(s/continuous-subseqs string?)
|
||||
(fn [s] [(apply str s)])
|
||||
[1 "a" "b" 2 3 "c" 4 "d" "e" "f"]
|
||||
)))
|
||||
(is (= [[] [2] [4 6]]
|
||||
(select
|
||||
[(s/continuous-subseqs number?) (s/filterer even?)]
|
||||
[1 "a" "b" 2 3 "c" 4 5 6 "d" "e" "f"]
|
||||
)))
|
||||
)
|
||||
|
|
|
|||
Loading…
Reference in a new issue