Add implementation for three new sorting navs

This commit is contained in:
Joshua Suskalo 2021-08-23 08:57:09 -05:00
parent d0d6fdf581
commit 7abc71bbed
3 changed files with 73 additions and 0 deletions

View file

@ -1504,3 +1504,61 @@
[& path]
(map compact* path)
))
(defnav
^{:doc "Navigates to a sequence resulting from (sort ...), but is a
view to the original structure that can be transformed.
If the transformed sequence is smaller than the input sequence, values
which are included are sorted by the same indices as the input value's
index in the input sequence.
If the transformed sequence is larger than the input sequence, values
added to the end of the sequence will be appended to the end of the
original sequence."}
SORTED
[]
(select* [this structure next-fn]
(n/sorted-select structure identity compare next-fn))
(transform* [this structure next-fn]
(n/sorted-transform structure identity compare next-fn)))
(defnav
^{:doc "Navigates to a sequence resulting from (sort comparator ...), but
is a view to the original structure that can be transformed.
If the transformed sequence is smaller than the input sequence, values
which are included are sorted by the same indices as the input value's
index in the input sequence.
If the transformed sequence is larger than the input sequence, values
added to the end of the sequence will be appended to the end of the
original sequence."}
sorted
[comparator]
(select* [this structure next-fn]
(n/sorted-select structure identity comparator next-fn))
(transform* [this structure next-fn]
(n/sorted-transform structure identity comparator next-fn)))
(defdynamicnav sorted-by
"Navigates to a sequence sorted by the value stored in the keypath, by the
comparator, if one is provided.
This sequence is a view to the original structure that can be transformed. If
the transformed sequence is smaller than the input sequence, values which are
included are sorted by the same indices as the input value's index in the
input sequence.
If the transformed sequence is larger than the input sequence, values added to
the end of the sequence will be appended to the end of the original sequence.
Value collection (e.g. collect, collect-one) may not be used in the keypath."
([keypath] (sorted-by keypath compare))
([keypath comparator]
(late-bound-nav [late (late-path keypath)
late-fn comparator]
(select* [this structure next-fn]
(n/sorted-select structure #(compiled-select late %) late-fn next-fn))
(transform* [this structure next-fn]
(n/sorted-transform structure #(compiled-select late %) late-fn next-fn)))))

View file

@ -546,6 +546,16 @@
res
))))
(defn sorted-transform*
[structure keyfn comparator next-fn]
(let [sorted (sort-by (comp keyfn second) comparator (map-indexed vector structure))
indices (map first sorted)
result (next-fn (map second sorted))
unsorted (sort-by first compare (map vector (concat indices (repeat ##Inf)) result))]
(into (empty structure)
(map second)
unsorted)))
(defn- matching-indices [aseq p]
(keep-indexed (fn [i e] (if (p e) i)) aseq))

View file

@ -381,6 +381,11 @@
(def srange-transform i/srange-transform*)
(defn sorted-select
[structure keyfn comparator next-fn]
(next-fn (sort-by keyfn comparator structure)))
(def sorted-transform i/sorted-transform*)
(defn extract-basic-filter-fn [path]
(cond (fn? path)