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
(comment
[{: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
(comment
((: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]
             (reduce-kv
               (fn [rows i col]
                 (assoc-in rows [i k] col))
               rows cols))
  []
  optij)

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.
Thx!
-kt

--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
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 [email protected].
For more options, visit https://groups.google.com/d/optout.



Programming list archiving by: Enterprise Git Hosting