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.
* `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
* Extend `srange`, `BEGINNING`, `END`, `FIRST`, and `LAST` on strings to navigate to substrings
* Improved `ALL` performance for PersistentHashSet
* Dynamic navs automatically compile sequence returns if completely static
* Eliminate reflection warnings for clj (thanks @mpenet)

View file

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

View file

@ -521,14 +521,21 @@
(mk-comp-navs)
(defn srange-transform* [structure start end next-fn]
(let [structurev (vec structure)
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)))
(if (string? structure)
(let [newss (next-fn (subs structure start end))]
(str (subs structure 0 start)
newss
(subs structure end (count structure))
))
(let [structurev (vec structure)
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]
(keep-indexed (fn [i e] (if (p e) i)) aseq))

View file

@ -298,7 +298,11 @@
(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*)
@ -430,6 +434,15 @@
(let [i (dec c)]
(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)
(update-first [l val]
(update-first-list l val))
@ -443,11 +456,19 @@
(nth v 0))
(get-last [v]
(peek v))
#?(:clj Object :cljs default)
(get-first [s]
(first 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" '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"))
)