extend srange, BEGINNING, END, FIRST, and LAST to strings

This commit is contained in:
nathanmarz 2017-02-15 18:30:44 -05:00
parent ffcba01df7
commit 7c798c1e3b
5 changed files with 62 additions and 17 deletions

View file

@ -6,6 +6,7 @@
* Added `traverse-all` which returns a transducer that traverses over all elements matching the given path. * Added `traverse-all` which returns a transducer that traverses over all elements matching the given path.
* `select-first` and `select-any` now avoid traversal beyond the first value matched by the path (like when using `ALL`), so they are faster now for those use cases. * `select-first` and `select-any` now avoid traversal beyond the first value matched by the path (like when using `ALL`), so they are faster now for those use cases.
* Add `NAME` and `NAMESPACE` navigators * Add `NAME` and `NAMESPACE` navigators
* Extend `srange`, `BEGINNING`, `END`, `FIRST`, and `LAST` on strings to navigate to substrings
* Improved `ALL` performance for PersistentHashSet * Improved `ALL` performance for PersistentHashSet
* Dynamic navs automatically compile sequence returns if completely static * Dynamic navs automatically compile sequence returns if completely static
* Eliminate reflection warnings for clj (thanks @mpenet) * Eliminate reflection warnings for clj (thanks @mpenet)

View file

@ -706,10 +706,12 @@
BEGINNING BEGINNING
[] []
(select* [this structure next-fn] (select* [this structure next-fn]
(next-fn [])) (next-fn (if (string? structure) "" [])))
(transform* [this structure next-fn] (transform* [this structure next-fn]
(let [to-prepend (next-fn [])] (if (string? structure)
(n/prepend-all structure to-prepend)))) (str (next-fn "") structure)
(let [to-prepend (next-fn [])]
(n/prepend-all structure to-prepend)))))
(defnav (defnav
@ -717,11 +719,12 @@
END END
[] []
(select* [this structure next-fn] (select* [this structure next-fn]
(next-fn [])) (next-fn (if (string? structure) "" [])))
(transform* [this structure next-fn] (transform* [this structure next-fn]
(let [to-append (next-fn [])] (if (string? structure)
(n/append-all structure to-append)))) (str structure (next-fn ""))
(let [to-append (next-fn [])]
(n/append-all structure to-append)))))
(defnav (defnav
^{:doc "Navigates to the specified subset (by taking an intersection). ^{:doc "Navigates to the specified subset (by taking an intersection).

View file

@ -521,14 +521,21 @@
(mk-comp-navs) (mk-comp-navs)
(defn srange-transform* [structure start end next-fn] (defn srange-transform* [structure start end next-fn]
(let [structurev (vec structure) (if (string? structure)
newpart (next-fn (-> structurev (subvec start end))) (let [newss (next-fn (subs structure start end))]
res (concat (subvec structurev 0 start) (str (subs structure 0 start)
newpart newss
(subvec structurev end (count structure)))] (subs structure end (count structure))
(if (vector? structure) ))
(vec res) (let [structurev (vec structure)
res))) newpart (next-fn (-> structurev (subvec start end)))
res (concat (subvec structurev 0 start)
newpart
(subvec structurev end (count structure)))]
(if (vector? structure)
(vec res)
res
))))
(defn- matching-indices [aseq p] (defn- matching-indices [aseq p]
(keep-indexed (fn [i e] (if (p e) i)) aseq)) (keep-indexed (fn [i e] (if (p e) i)) aseq))

View file

@ -298,7 +298,11 @@
(defn srange-select [structure start end next-fn] (defn srange-select [structure start end next-fn]
(next-fn (-> structure vec (subvec start end)))) (next-fn
(if (string? structure)
(subs structure start end)
(-> structure vec (subvec start end))
)))
(def srange-transform i/srange-transform*) (def srange-transform i/srange-transform*)
@ -430,6 +434,15 @@
(let [i (dec c)] (let [i (dec c)]
(assoc v i (afn (nth v i))))))) (assoc v i (afn (nth v i)))))))
#?(:clj String :cljs string)
(update-first [s afn]
(str (afn (nth s 0)) (subs s 1 (count s))))
(update-last [s afn]
(let [last-idx (-> s count dec)]
(str (subs s 0 last-idx) (afn (nth s last-idx)))
))
#?(:clj Object :cljs default) #?(:clj Object :cljs default)
(update-first [l val] (update-first [l val]
(update-first-list l val)) (update-first-list l val))
@ -443,11 +456,19 @@
(nth v 0)) (nth v 0))
(get-last [v] (get-last [v]
(peek v)) (peek v))
#?(:clj Object :cljs default) #?(:clj Object :cljs default)
(get-first [s] (get-first [s]
(first s)) (first s))
(get-last [s] (get-last [s]
(last s))) (last s))
#?(:clj String :cljs string)
(get-first [s]
(nth s 0))
(get-last [s]
(nth s (-> s count dec))
))

View file

@ -1419,3 +1419,16 @@
(= 'a/e (setval s/NAMESPACE "a" 'e)) (= 'a/e (setval s/NAMESPACE "a" 'e))
(= 'a/e (setval s/NAMESPACE "a" 'f/e)) (= 'a/e (setval s/NAMESPACE "a" 'f/e))
) )
(deftest string-navigation-test
(= "ad" (setval (s/srange 1 4) "" "abcd"))
(= "bc" (select-any (s/srange 1 4) "abcd"))
(= "ab" (setval s/END "b" "a"))
(= "ba" (setval s/BEGINNING "b" "a"))
(= "" (select-any s/BEGINNING "abc"))
(= "" (select-any s/END "abc"))
(= \a (select-any s/FIRST "abc"))
(= \c (select-any s/LAST "abc"))
(= "qbc" (setval s/FIRST \q "abc"))
(= "abq" (setval s/FIRST "q" "abc"))
)