Subject: Re: Simple clojure example improvements sought

On Tuesday, January 10, 2017 at 1:59:05 PM UTC-5, Francis Avila wrote:

On Tuesday, January 10, 2017 at 9:27:24 AM UTC-6, hiskennyness wrote:Whenever I code something like this I get the feeling a clojure guru could do it more simply, and I love learning new tricks.
Here is my simple (real-world, btw) problem and solution. Is there a better way?
;; Problem: given optimized* json maps (* to avoid duplicating keys):
(def optij {:name [:tom :dick :harry]
:age [1 2 3]
:tone [:do :re :mi]})

;; ... produce normal repetitious maps
[{:name :tom, :age 1, :tone :do}
{:name :dick, :age 2, :tone :re}
{:name :harry, :age 3, :tone :mi}])

;; goal #1: pivot so I can use zipmap
((:tom 1 :do) (:dick 2 :re) (:harry 3 :mi)))

;; my goal #1 approach (improvements welcome):
(apply (partial map (fn [& vs] vs))
(vals optij))

(apply (partial map vector)
(vals optij))

Your partials are not strictly necessary, apply "auto-partials" all but the last argument:
(apply map vector (vals optij))

Awesome. I tried applying map and it failed I guess because of something else so I gave up on it too soon.   
;; my overall approach (improvements welcome):
(let [ks (keys optij)
vs-pivoted (apply (partial map vector)
(vals optij))]
(vec (for [attributes vs-pivoted]
(zipmap ks attributes))))

This is a minor variation that uses transducers:(let [ks (keys optij)
      vs-pivoted (apply map vector (vals optij))]
  (into [] (map #(zipmap ks %)) vs-pivoted))
Nice. I fall back onto for-loops too quickly. 

This is a slightly different approach that combines keys and values first, then pivots:
(->> optij
     (map (fn [[attr vs]] (mapv #(do [attr %]) vs)))
     ;; [[[:name :tom][:name :dick]...], [[:age 1]...]]
     (apply mapv (fn [& cols]
                   ;; cols ([:name :tom] [:age 1] [:tone :do])
                   (into {} cols))))
This is a non-lazy approach that builds up the rows in multiple passes without intermediate pivots or seqs:
(reduce-kv (fn [rows k cols]
               (fn [rows i col]
                 (assoc-in rows [i k] col))
               rows cols))

Sweet. I did actually code originally something that plucked values by column but decided to try the pivot approach because my plucking was not as terse as that.

You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@xxxxxxxxxxxxxxxx
Note that posts from new members are moderated - please be patient with your first post.
To unsubscribe from this group, send email to
For more options, visit this group at
You received this message because you are subscribed to the Google Groups "Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscribe@xxxxxxxxxxxxxxxx.
For more options, visit

Programming list archiving by: Enterprise Git Hosting