/src/claro/projection/sort.cljc

https://github.com/xsc/claro · Clojure · 59 lines · 53 code · 5 blank · 1 comment · 1 complexity · 5319f82f35bf484b49b304a64534c993 MD5 · raw file

  1. (ns claro.projection.sort
  2. (:refer-clojure :exclude [sort-by])
  3. (:require [claro.projection
  4. [protocols :as p]
  5. [transform :as transform]]
  6. [claro.data
  7. [error :refer [with-error?]]
  8. [ops :as ops]]))
  9. (deftype SortProjection [sort-template output-template]
  10. p/Projection
  11. (project [_ original]
  12. (with-error? original
  13. (->> (fn [sq]
  14. (-> (transform/transform
  15. (fn [sort-keys]
  16. (->> (map vector sort-keys sq)
  17. (clojure.core/sort-by first)
  18. (mapv second)))
  19. [sort-template]
  20. output-template)
  21. (p/project sq)))
  22. (ops/then original)))))
  23. (defmethod print-method SortProjection
  24. [^SortProjection value ^java.io.Writer w]
  25. (.write w "#<claro/sort-by ")
  26. (print-method (.-sort-template value) w)
  27. (when-let [out (.-output-template value)]
  28. (.write w " -> ")
  29. (print-method out w))
  30. (.write w ">"))
  31. (defn ^{:added "0.2.19"} sort-by
  32. "A projection sorting the sequence that's currently being resolved.
  33. `sort-template` is applied to each element of the sequence to generate
  34. a value to sort by, while `output-template´ is used to further project
  35. the resulting sorted sequence.
  36. ```clojure
  37. (-> [{:index 3, :value 'third}
  38. {:index 1, :value 'first}
  39. {:index 2, :value 'second}]
  40. (projection/apply
  41. (projection/sort-by
  42. (projection/extract :index)
  43. [{:value projection/leaf}]))
  44. (engine/run!!))
  45. ;; => [{:value 'first}, {:value 'second}, {:value 'third}]
  46. ```
  47. If no `output-template` is given, the resulting tree may not be infinite
  48. (or a further projection has to be applied externally)."
  49. ([sort-template]
  50. (->SortProjection sort-template nil))
  51. ([sort-template output-template]
  52. {:pre [(some? sort-template)
  53. (some? output-template)]}
  54. (->SortProjection sort-template output-template)))