Reputation: 973
In my continual effort to replicate imperative programming in Clojure, I seem to still nest for
functions.
For example, if I wanted to start with:
[[{:a 1 :b 2 :c 3} {:a 1 :b 2 :c 3}] [{:a 2 :b 2 :c 3} {:a 2 :b 2 :c 3}]]
and get:
[[:table [:tr [:td {:class "a-1" "b-2" "c-3"}] [:td {:class "a-2" "b-2" "c-3"}]]
how would I do that without the classic nested for
statements I'm familiar with from other languages?
I realize I should paste my attempt here but it's too awful.
UPDATE: see the point below that I used incorrect hiccup in the :class values.
Upvotes: 1
Views: 150
Reputation: 3346
My recommendation would be to see the structure of the data (which you have already) and try to decompose the problem in terms of the data you are given.
You have a structure which resembles rows and cells, so that's one approach. You format rows, which are the result of formatting individual cells, then each cell needs to have CSS classes which are passed as a hash-map.
With that in mind:
(defn cell-classes [cell]
(->> (map (fn [[k v]] (str (name k) "-" v)) cell)
(interpose " ")
(reduce str)))
(defn format-cell [cell]
(let [classes (cell-classes cell)]
[:td {:class classes}]))
(defn format-row [cells]
(->> (map format-cell cells)
(into [:tr])))
(defn format-rows [rows]
(->> (map format-row rows)
(into [:table])))
If we test it with your sample data:
(clojure.pprint/pprint (format-rows [[{:a 1 :b 2 :c 3} {:a 1 :b 2 :c 3}] [{:a 2 :b 2 :c 3} {:a 2 :b 2 :c 3}]]))
it prints
[:table
[:tr [:td {:class "a-1 b-2 c-3"}] [:td {:class "a-1 b-2 c-3"}]]
[:tr [:td {:class "a-2 b-2 c-3"}] [:td {:class "a-2 b-2 c-3"}]]]
PS: there's a minor issue in your desired output, which is that {:class "a-1" "b-2" "c-3"}
would not be a desirable output for hiccup, that's why I joined the class names with space on cell-classes
.
Upvotes: 3