-
-
Save zachmandeville/3f4f805b5bc6dae3bd67c9899f48a832 to your computer and use it in GitHub Desktop.
Clojure Refactor
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; Goal: | |
;; I have an array of data showing stores, and dollars spent at the store | |
(def input-data [{:month "06/21", :store "Mitesh", :total 5.9} | |
{:month "07/21", :store "Mitesh", :total 5.5} | |
{:month "07/21", :store "Moore Wilson", :total 85.16} | |
{:month "06/21", :store "Moore Wilson", :total 33.45} | |
{:month "07/21", :store "New World", :total 75.26} | |
{:month "06/21", :store "New World", :total 84.28} | |
{:month "06/21", :store "Pak n Save", :total 26} | |
{:month "07/21", :store "Pak n Save", :total 200.36}]) | |
;; I want to transform it into a valid data object for a chart.js bar chart | |
;; Where the x-axis is months, y-axis is the dollar total, and the data is stacked by store. | |
;; the desired end result would look like so: | |
(def desired-data | |
{:datasets ({:label Pak n Save, :backgroundColor #BBAB8B, :data (26 200.36)} | |
{:label New World, :backgroundColor #EF8275, :data (84.28 75.26)} | |
{:label Moore Wilson, :backgroundColor #88A096, :data (33.45 85.16)} | |
{:label Mitesh, :backgroundColor #8A4F7D, :data (5.9 5.5)}) | |
:labels (07/21 06/21)}) | |
;; My current function groups the input data by store, then does a reduce to create | |
;; the proper datasets and labels maps. It feels wordy and a bit hard to follow now, | |
;; but i like that it is a single declarative function. | |
(let [store-colors ;; (the assignment of colour will be improved, but that's a separate topic) | |
{"Moore Wilson" "#88A096" | |
"Pak n Save" "#BBAB8B" | |
"Mitesh" "#8A4F7D" | |
"New World" "#EF8275"}] | |
(reduce-kv (fn [m k v] | |
(-> m (assoc :datasets (cons | |
(reduce (fn [acc {:keys [store]}] | |
(-> acc | |
(assoc :label store) | |
(assoc :backgroundColor (get store-colors store)) | |
(assoc :data (map :total (sort-by :month v))))) | |
{} v) | |
(:datasets m))) | |
(assoc :labels (set (into (:labels m) (map :month v)))))) | |
{:labels [] :datasets []} | |
(group-by :store input-data))) | |
;; I am curious: is there a simpler way to do this transformation? | |
;; Are there any "gotcha" logical holes in my function that could make the resulting data inaccurate? | |
(println "Thank you!") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
With the help of Cora and SeanCorfield from the clojurian slack, this was refactored to:
My thanks to them!