Re: Simple clojure example improvements sought

2017-01-10 Thread Beau Fabry
Haha, the one line was more an artifact of me entering it that way than a 
recommendation, if I was committing to master it would probably look like

(map-indexed
  (fn [person-num _person_name]
(->> optij
(map (fn [[attribute-name attribute-vals]] {attribute-name (nth 
attribute-vals person-num)}))
(into {})))
  (:name optij))

On Tuesday, January 10, 2017 at 6:13:28 PM UTC-8, hiskennyness wrote:
>
>
>
> On Tuesday, January 10, 2017 at 2:37:22 PM UTC-5, Beau Fabry wrote:
>>
>> With specter:
>>
>> (map-indexed (fn [i name] (sp/transform sp/MAP-VALS #(nth % i) optij)) 
>> (:name optij))
>> => ({:name :tom, :age 1, :tone :do} {:name :dick, :age 2, :tone :re} 
>> {:name :harry, :age 3, :tone :mi})
>>
>
> One line! With specter, but still nice.
>
> But to me this is the downside of specter and even Clojure: the code 
> starts to get opaque. I am reminded of the C Puzzle Book which offered 
> simple data and a few lines of code and defied us to guess what the code 
> produced.
>
> My big take-away here is map-indexed. Forgot about that and it would have 
> greatly simplified my original efforts.
>  
>
>>
>> Without:
>>
>> (map-indexed (fn [i name] (into {} (map (fn [[k v]] [k (nth v i)]) 
>> optij))) (:name optij))
>> => ({:name :tom, :age 1, :tone :do} {:name :dick, :age 2, :tone :re} 
>> {:name :harry, :age 3, :tone :mi})
>>
>>
> Gonna have to study that one. :) Still one line, tho! Cool.
>
> -kt
>
>>
>>>

-- 
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.


Re: Simple clojure example improvements sought

2017-01-10 Thread hiskennyness


On Tuesday, January 10, 2017 at 2:37:22 PM UTC-5, Beau Fabry wrote:
>
> With specter:
>
> (map-indexed (fn [i name] (sp/transform sp/MAP-VALS #(nth % i) optij)) 
> (:name optij))
> => ({:name :tom, :age 1, :tone :do} {:name :dick, :age 2, :tone :re} 
> {:name :harry, :age 3, :tone :mi})
>

One line! With specter, but still nice.

But to me this is the downside of specter and even Clojure: the code starts 
to get opaque. I am reminded of the C Puzzle Book which offered simple data 
and a few lines of code and defied us to guess what the code produced.

My big take-away here is map-indexed. Forgot about that and it would have 
greatly simplified my original efforts.
 

>
> Without:
>
> (map-indexed (fn [i name] (into {} (map (fn [[k v]] [k (nth v i)]) 
> optij))) (:name optij))
> => ({:name :tom, :age 1, :tone :do} {:name :dick, :age 2, :tone :re} 
> {:name :harry, :age 3, :tone :mi})
>
>
Gonna have to study that one. :) Still one line, tho! Cool.

-kt

>
>>

-- 
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.


Re: Simple clojure example improvements sought

2017-01-10 Thread hiskennyness


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 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.


Re: Simple clojure example improvements sought

2017-01-10 Thread Beau Fabry
sorry that last nth should've been (nth % i nil)

On Tuesday, January 10, 2017 at 11:37:22 AM UTC-8, Beau Fabry wrote:
>
> With specter:
>
> (map-indexed (fn [i name] (sp/transform sp/MAP-VALS #(nth % i) optij)) 
> (:name optij))
> => ({:name :tom, :age 1, :tone :do} {:name :dick, :age 2, :tone :re} 
> {:name :harry, :age 3, :tone :mi})
>
> Without:
>
> (map-indexed (fn [i name] (into {} (map (fn [[k v]] [k (nth v i)]) 
> optij))) (:name optij))
> => ({:name :tom, :age 1, :tone :do} {:name :dick, :age 2, :tone :re} 
> {:name :harry, :age 3, :tone :mi})
>
> If I didn't know which key was the canonical full list, ie some could be 
> shorter and in that case I wanted nil:
>
> (map (fn [i] (sp/transform sp/MAP-VALS #(nth % i) optij)) (range 0 (inc 
> (apply max (map (comp count vals) optij)
> => ({:name :tom, :age 1, :tone :do} {:name :dick, :age 2, :tone :re} 
> {:name :harry, :age 3, :tone :mi})
>
>
> On Tuesday, January 10, 2017 at 7:27:24 AM UTC-8, 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))
>>
>> ;; 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
>>
>>
>> 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.
>>
>

-- 
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.


Re: Simple clojure example improvements sought

2017-01-10 Thread Beau Fabry
With specter:

(map-indexed (fn [i name] (sp/transform sp/MAP-VALS #(nth % i) optij)) 
(:name optij))
=> ({:name :tom, :age 1, :tone :do} {:name :dick, :age 2, :tone :re} {:name 
:harry, :age 3, :tone :mi})

Without:

(map-indexed (fn [i name] (into {} (map (fn [[k v]] [k (nth v i)]) optij))) 
(:name optij))
=> ({:name :tom, :age 1, :tone :do} {:name :dick, :age 2, :tone :re} {:name 
:harry, :age 3, :tone :mi})

If I didn't know which key was the canonical full list, ie some could be 
shorter and in that case I wanted nil:

(map (fn [i] (sp/transform sp/MAP-VALS #(nth % i) optij)) (range 0 (inc 
(apply max (map (comp count vals) optij)
=> ({:name :tom, :age 1, :tone :do} {:name :dick, :age 2, :tone :re} {:name 
:harry, :age 3, :tone :mi})


On Tuesday, January 10, 2017 at 7:27:24 AM UTC-8, 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))
>
> ;; 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
>
>
> 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.
>

-- 
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.


Re: Simple clojure example improvements sought

2017-01-10 Thread Francis Avila


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.


Simple clojure example improvements sought

2017-01-10 Thread hiskennyness
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))

;; 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


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.

-- 
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.