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)) > ;; 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)) 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) Final fun question: is the original idea of compressing JSON this way > commonplace? I thought everyone was just saying to hell with the > duplication and taking the convenience of self-defining objects, but > apparently one source is not. > I don't know. -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com 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 clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.