This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2024-02-02
Channels
- # announcements (4)
- # babashka (1)
- # beginners (4)
- # cider (4)
- # clerk (3)
- # clojure (25)
- # clojure-brasil (5)
- # clojure-europe (6)
- # clojure-nl (1)
- # clojure-norway (48)
- # clojure-uk (4)
- # clojuredesign-podcast (3)
- # clojurescript (1)
- # conjure (1)
- # emacs (23)
- # hyperfiddle (3)
- # jobs (6)
- # lsp (12)
- # off-topic (5)
- # polylith (13)
- # reagent (8)
- # reitit (18)
- # sci (20)
- # shadow-cljs (8)
- # specter (3)
- # squint (3)
last question for now 🙏 can you help me combine this into one path? i want to filter on cost type :labor
, then sum labor hours by category. getting tripped up on the group-by.
(def -line-items
[{:line-item/cost-type :labor
:line-item/category "Piping"
:labor/total-hours 5}
{:line-item/cost-type :labor
:line-item/category "Sheet Metal"
:labor/total-hours 8}
{:line-item/cost-type :labor
:line-item/category "Piping"
:labor/total-hours 7}
{:line-item/cost-type :material
:line-item/category "Piping"
:material/cost 500}
{:line-item/cost-type :material
:line-item/category "Sheet Metal"
:material/cost 300}
{:line-item/cost-type :labor
:line-item/category "Sheet Metal"
:labor/total-hours 4}])
;; filter on cost type :labor, then sum labor hours by category
(->> -line-items
(sp/select [sp/ALL (comp #{:labor} :line-item/cost-type)])
(group-by :line-item/category)
(sp/transform [sp/MAP-VALS (sp/view #(sp/select [sp/ALL :labor/total-hours number?] %))]
#(reduce + 0 %)))
;; => {"Piping" 12, "Sheet Metal" 12}
i tried copying this from examples but i'm misunderstanding how group-by-nav
works.
(sp/defnav group-by-view [key]
(select* [this structure next-fn]
(next-fn (group-by key structure)))
(transform* [this structure next-fn]
(next-fn (group-by key structure))))
(defn group-by-nav [f] (sp/path (group-by-view f) sp/ALL sp/LAST))
(->> -line-items
(sp/transform [sp/ALL (comp #{:labor} :line-item/cost-type)
(group-by-nav :line-item/category)
sp/MAP-VALS (sp/view #(sp/select [sp/ALL :labor/total-hours number?] %))]
#(reduce + 0 %)))
nevermind, i found a better approach that doesn't involve group-by. seems like group-by can be a bit of an antipattern when applying specter
just for completeness, i came up with a solution that uses group-by-view
. any suggestions would be appreciated.
(sp/transform [(group-by-view :line-item/category)
sp/ALL
(sp/collect-one sp/FIRST)
(sp/collect
sp/LAST
sp/ALL
(comp #{:labor} :line-item/cost-type)
:labor/total-hours)]
(fn [k v v2]
[k (reduce + 0 v)])
-line-items)