Re: Is This Function Idiomatic Clojure?
My take on this. I know it's convoluted, I know this is probably not the best and not even a good-enough solution, but it's what I have so far (needless to say, I'd welcome comments on my code :) (defn explode [ [k vals ] ] (map #(vector key %) vals)) (defn update-map [ m ] (partial apply assoc m)) user> (map (update-map {}) (apply map into (map explode [[:head [1 2 3]] [:tail [:a :b :c]]]))) ({:tail :a, :head 1} {:tail :b, :head 2} {:tail :c, :head 3}) Cheers, U -- 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
Re: Is This Function Idiomatic Clojure?
Thanks again for these beautiful code examples! I haven't come across (apply map ... before so this is idiom a big step forward for me. The same is true for the extended use of 'reduce'. I know that this function is really powerful but I am only just beginning to understand its potential. Sometimes I feel a bit overwhelmed by the flexibility of Clojure. Therefore, reading idiomatic code like your examples really helps me a lot. Stefan -- 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
Re: Is This Function Idiomatic Clojure?
Hi, On 7 Okt., 08:29, Stefan Rohlfing wrote: > (defn d-map [& kfps] > (let [keys (map first kfps) > fns (map second kfps)] > (loop [keys keys fns fns res []] > (if (seq keys) > (recur (rest keys) (rest fns) > (into res (map (fn [x] [(first keys) x]) (first > fns > res Since no one mentioned reduce, here some variations. Your looping construct with an accumulator which is simply returned should ring a bell for reduce in your head. (defn d-map [& kfps] (reduce (fn [res [k vs]] (reduce #(conj %1 [k %2]) res vs)) [] kfps)) (defn d-map [& kfps] (reduce (fn [res [k vs]] (reduce conj res (map vector (repeat k) vs)) [] kfps))) I would expect the first to be slightly faster. While the second might be a little cleaner from an esoterical point of view. Sincerely Meikel -- 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
Re: Is This Function Idiomatic Clojure?
And I was about to post this variant ... looks very similar to yours :) (apply map merge (for [[k vs] args] (for [v vs] {k v}))) I think the crux is "apply map"... my go-to idiom for parallel iteration over an arbitrary number of seqs. On Oct 7, 1:26 am, Per Vognsen wrote: > Since variety is the spice of life, here's my (less clean and > untested) code that I was about to post when your message arrived in > my inbox: > > (apply map #(into {} %) (for [[k vs] args] (for [v vs] [k v] > > -Per > > On Thu, Oct 7, 2010 at 3:18 PM, Jason Wolfe wrote: > > (defn d-map [& args] > > (apply map > > (fn [& vals] (zipmap (map first args) vals)) > > (map second args))) > > > On Oct 7, 12:54 am, Stefan Rohlfing wrote: > >> Thank you all for your great code examples! > > >> The goal of the function 'd-map' is to return a collection of maps > >> that looks like this: > > >> ({:headline "this", :points 1, :comments 10} > >> {:headline "is", :points 2, :comments 20} > >> {:headline "me", :points 3, :comments 30}) > > >> Based on Per's example using 'for' I came up with the following > >> implementation: > > >> (d-map [:headline ["this" "is" "me"] ] > >> [:points [1 2 3] ] > >> [:comments [10 20 30] ]) > > >> (defn d-map [& args] > >> (let [kv-list (for [ [head items] args, item items] [head item]) > >> len (count args)] > >> (map #(into {} %) > >> (partition len (apply interleave (partition len kv- > >> list)) > > >> This is quite a few functions for turning 'kv-list': > > >> ([:headline "this"] [:headline "is"] [:headline "me"] [:points 1] > >> [:points 2] ...) > > >> into: > >> ({:headline "this", :points 1, :comments 10} {:headline "is", :points > >> 2, ...} ...) > > >> Therefore, I would like to ask again if there is a more elegant way to > >> get to this result. > > >> Stefan > > > -- > > You received this message because you are subscribed to the Google > > Groups "Clojure" group.> To post to this group, send email > > tocloj...@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 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
Re: Is This Function Idiomatic Clojure?
Since variety is the spice of life, here's my (less clean and untested) code that I was about to post when your message arrived in my inbox: (apply map #(into {} %) (for [[k vs] args] (for [v vs] [k v] -Per On Thu, Oct 7, 2010 at 3:18 PM, Jason Wolfe wrote: > (defn d-map [& args] > (apply map > (fn [& vals] (zipmap (map first args) vals)) > (map second args))) > > On Oct 7, 12:54 am, Stefan Rohlfing wrote: >> Thank you all for your great code examples! >> >> The goal of the function 'd-map' is to return a collection of maps >> that looks like this: >> >> ({:headline "this", :points 1, :comments 10} >> {:headline "is", :points 2, :comments 20} >> {:headline "me", :points 3, :comments 30}) >> >> Based on Per's example using 'for' I came up with the following >> implementation: >> >> (d-map [:headline ["this" "is" "me"] ] >> [:points [1 2 3] ] >> [:comments [10 20 30] ]) >> >> (defn d-map [& args] >> (let [kv-list (for [ [head items] args, item items] [head item]) >> len (count args)] >> (map #(into {} %) >> (partition len (apply interleave (partition len kv- >> list)) >> >> This is quite a few functions for turning 'kv-list': >> >> ([:headline "this"] [:headline "is"] [:headline "me"] [:points 1] >> [:points 2] ...) >> >> into: >> ({:headline "this", :points 1, :comments 10} {:headline "is", :points >> 2, ...} ...) >> >> Therefore, I would like to ask again if there is a more elegant way to >> get to this result. >> >> Stefan > > -- > 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 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
Re: Is This Function Idiomatic Clojure?
(defn d-map [& args] (apply map (fn [& vals] (zipmap (map first args) vals)) (map second args))) On Oct 7, 12:54 am, Stefan Rohlfing wrote: > Thank you all for your great code examples! > > The goal of the function 'd-map' is to return a collection of maps > that looks like this: > > ({:headline "this", :points 1, :comments 10} > {:headline "is", :points 2, :comments 20} > {:headline "me", :points 3, :comments 30}) > > Based on Per's example using 'for' I came up with the following > implementation: > > (d-map [:headline ["this" "is" "me"] ] > [:points [1 2 3] ] > [:comments [10 20 30] ]) > > (defn d-map [& args] > (let [kv-list (for [ [head items] args, item items] [head item]) > len (count args)] > (map #(into {} %) > (partition len (apply interleave (partition len kv- > list)) > > This is quite a few functions for turning 'kv-list': > > ([:headline "this"] [:headline "is"] [:headline "me"] [:points 1] > [:points 2] ...) > > into: > ({:headline "this", :points 1, :comments 10} {:headline "is", :points > 2, ...} ...) > > Therefore, I would like to ask again if there is a more elegant way to > get to this result. > > Stefan -- 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
Re: Is This Function Idiomatic Clojure?
Thank you all for your great code examples! The goal of the function 'd-map' is to return a collection of maps that looks like this: ({:headline "this", :points 1, :comments 10} {:headline "is", :points 2, :comments 20} {:headline "me", :points 3, :comments 30}) Based on Per's example using 'for' I came up with the following implementation: (d-map [:headline ["this" "is" "me"] ] [:points [1 2 3] ] [:comments [10 20 30] ]) (defn d-map [& args] (let [kv-list (for [ [head items] args, item items] [head item]) len (count args)] (map #(into {} %) (partition len (apply interleave (partition len kv- list)) This is quite a few functions for turning 'kv-list': ([:headline "this"] [:headline "is"] [:headline "me"] [:points 1] [:points 2] ...) into: ({:headline "this", :points 1, :comments 10} {:headline "is", :points 2, ...} ...) Therefore, I would like to ask again if there is a more elegant way to get to this result. Stefan -- 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
Re: Is This Function Idiomatic Clojure?
Thats what I came up with this. (defn getpairs [[key coll]] ;; split the key form the data (http:// blog.jayfields.com/2010/07/clojure-destructuring.html) (map (fn [x] [key x]) coll)) ;;put the key in front of every element in data (defn d-map [& colls] (mapcat getpairs colls)) ;;mapcat is just connecting the diffrenct return values. (concat (map getpairs coll)) -- 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
Re: Is This Function Idiomatic Clojure?
On Oct 7, 2010, at 2:29 AM, Stefan Rohlfing wrote: > Dear Clojure Group, > > Following an Enlive tutorial I wanted to implement a function 'd-map' > that takes an arbitrary number of [:key (list of values)] parameters > like this: > > (d-map [:headline ["this" "is" "me"] ] > [:points [1 2 3] ] > [:comments [10 20 30] ]) > > > and returns a collection of [:key value] vectors where each value is > grouped with its respective key: > > [ [:headline "this"] [:headline "is"] [:headline "me"] > [:points 1] [:points 2] [:points 3] > [:comments 10] [:comments 20] [:comments 30] ] > > > I could only come up with the following implementation for 'd-map'. > Although it works it just does not 'feel' elegant of even very > functional: > > (defn d-map [& kfps] > (let [keys (map first kfps) >fns (map second kfps)] >(loop [keys keys fns fns res []] > (if (seq keys) > (recur (rest keys) (rest fns) > (into res (map (fn [x] [(first keys) x]) (first > fns > res If you treat a map as a sequence it will yield the vectors you are handling explicitly: (map identity {:a [1 2 3] :b [4 5 6]}) => ([:a [1 2 3]] [:b [4 5 6]]) So it might be more convenient to pass in a map and do something like this: (defn d-map [m] (apply concat (map (fn [[key val-list]] (map (fn [val] [key val]) val-list)) m))) (d-map {:headline ["this" "is" "me"] :points [1 2 3] :comments [10 20 30]}) ([:headline "this"] [:headline "is"] [:headline "me"] [:points 1] [:points 2] [:points 3] [:comments 10] [:comments 20] [:comments 30]) Have all good days, David Sletten -- 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
Re: Is This Function Idiomatic Clojure?
Hello, All in all, you only used in your first definition "core" clojure constructs, you avoided doing "imperative in clojure clothes". So, while not leveraging to its full extent the power of clojure standard library functions and higher-order-functions, your code certainly qualifies as functional and in the spirit of clojure. 2010/10/7 Stefan Rohlfing > Dear Clojure Group, > > Following an Enlive tutorial I wanted to implement a function 'd-map' > that takes an arbitrary number of [:key (list of values)] parameters > like this: > > (d-map [:headline ["this" "is" "me"] ] >[:points [1 2 3] ] >[:comments [10 20 30] ]) > > > and returns a collection of [:key value] vectors where each value is > grouped with its respective key: > > [ [:headline "this"] [:headline "is"] [:headline "me"] > [:points 1] [:points 2] [:points 3] > [:comments 10] [:comments 20] [:comments 30] ] > > > I could only come up with the following implementation for 'd-map'. > Although it works it just does not 'feel' elegant of even very > functional: > > (defn d-map [& kfps] > (let [keys (map first kfps) > fns (map second kfps)] >(loop [keys keys fns fns res []] > (if (seq keys) >(recur (rest keys) (rest fns) > (into res (map (fn [x] [(first keys) x]) (first > fns >res > > I am relatively new to Clojure and want to learn how to write > idiomatic code. I therefore appreciate any alternative implementation > that might help me learn some new things. > > Stefan > > -- > 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 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
Re: Is This Function Idiomatic Clojure?
Your manual composition of concat and map is the same as the built-in function mapcat. Anyway, all this is what (for ...) does for you under the covers. -Per On Thu, Oct 7, 2010 at 1:52 PM, Michael Gardner wrote: > On Oct 7, 2010, at 1:29 AM, Stefan Rohlfing wrote: > >> Following an Enlive tutorial I wanted to implement a function 'd-map' >> that takes an arbitrary number of [:key (list of values)] parameters >> like this: >> >> (d-map [:headline ["this" "is" "me"] ] >> [:points [1 2 3] ] >> [:comments [10 20 30] ]) >> >> >> and returns a collection of [:key value] vectors where each value is >> grouped with its respective key: >> >> [ [:headline "this"] [:headline "is"] [:headline "me"] >> [:points 1] [:points 2] [:points 3] >> [:comments 10] [:comments 20] [:comments 30] ] > > I'd do something like: > > (defn d-map [& kvs] > (apply concat > (map > (fn [[key vals]] > (map (partial vector key) vals)) > kvs))) > > -- > 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 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
Re: Is This Function Idiomatic Clojure?
Sorry, the 'in' is obviously a typo and should be left out. I tested the code in the REPL but then retyped it from memory rather than copy and pasting. :) -Per On Thu, Oct 7, 2010 at 1:53 PM, Per Vognsen wrote: > Try something like this: > > (defn dmap [& args] > (for [[head items] args] > item in items] > [head item])) > > -Per > > On Thu, Oct 7, 2010 at 1:29 PM, Stefan Rohlfing > wrote: >> Dear Clojure Group, >> >> Following an Enlive tutorial I wanted to implement a function 'd-map' >> that takes an arbitrary number of [:key (list of values)] parameters >> like this: >> >> (d-map [:headline ["this" "is" "me"] ] >> [:points [1 2 3] ] >> [:comments [10 20 30] ]) >> >> >> and returns a collection of [:key value] vectors where each value is >> grouped with its respective key: >> >> [ [:headline "this"] [:headline "is"] [:headline "me"] >> [:points 1] [:points 2] [:points 3] >> [:comments 10] [:comments 20] [:comments 30] ] >> >> >> I could only come up with the following implementation for 'd-map'. >> Although it works it just does not 'feel' elegant of even very >> functional: >> >> (defn d-map [& kfps] >> (let [keys (map first kfps) >> fns (map second kfps)] >> (loop [keys keys fns fns res []] >> (if (seq keys) >> (recur (rest keys) (rest fns) >> (into res (map (fn [x] [(first keys) x]) (first >> fns >> res >> >> I am relatively new to Clojure and want to learn how to write >> idiomatic code. I therefore appreciate any alternative implementation >> that might help me learn some new things. >> >> Stefan >> >> -- >> 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 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
Re: Is This Function Idiomatic Clojure?
Try something like this: (defn dmap [& args] (for [[head items] args] item in items] [head item])) -Per On Thu, Oct 7, 2010 at 1:29 PM, Stefan Rohlfing wrote: > Dear Clojure Group, > > Following an Enlive tutorial I wanted to implement a function 'd-map' > that takes an arbitrary number of [:key (list of values)] parameters > like this: > > (d-map [:headline ["this" "is" "me"] ] > [:points [1 2 3] ] > [:comments [10 20 30] ]) > > > and returns a collection of [:key value] vectors where each value is > grouped with its respective key: > > [ [:headline "this"] [:headline "is"] [:headline "me"] > [:points 1] [:points 2] [:points 3] > [:comments 10] [:comments 20] [:comments 30] ] > > > I could only come up with the following implementation for 'd-map'. > Although it works it just does not 'feel' elegant of even very > functional: > > (defn d-map [& kfps] > (let [keys (map first kfps) > fns (map second kfps)] > (loop [keys keys fns fns res []] > (if (seq keys) > (recur (rest keys) (rest fns) > (into res (map (fn [x] [(first keys) x]) (first > fns > res > > I am relatively new to Clojure and want to learn how to write > idiomatic code. I therefore appreciate any alternative implementation > that might help me learn some new things. > > Stefan > > -- > 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 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
Re: Is This Function Idiomatic Clojure?
On Oct 7, 2010, at 1:29 AM, Stefan Rohlfing wrote: > Following an Enlive tutorial I wanted to implement a function 'd-map' > that takes an arbitrary number of [:key (list of values)] parameters > like this: > > (d-map [:headline ["this" "is" "me"] ] > [:points [1 2 3] ] > [:comments [10 20 30] ]) > > > and returns a collection of [:key value] vectors where each value is > grouped with its respective key: > > [ [:headline "this"] [:headline "is"] [:headline "me"] > [:points 1] [:points 2] [:points 3] > [:comments 10] [:comments 20] [:comments 30] ] I'd do something like: (defn d-map [& kvs] (apply concat (map (fn [[key vals]] (map (partial vector key) vals)) kvs))) -- 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
Is This Function Idiomatic Clojure?
Dear Clojure Group, Following an Enlive tutorial I wanted to implement a function 'd-map' that takes an arbitrary number of [:key (list of values)] parameters like this: (d-map [:headline ["this" "is" "me"] ] [:points [1 2 3] ] [:comments [10 20 30] ]) and returns a collection of [:key value] vectors where each value is grouped with its respective key: [ [:headline "this"] [:headline "is"] [:headline "me"] [:points 1] [:points 2] [:points 3] [:comments 10] [:comments 20] [:comments 30] ] I could only come up with the following implementation for 'd-map'. Although it works it just does not 'feel' elegant of even very functional: (defn d-map [& kfps] (let [keys (map first kfps) fns (map second kfps)] (loop [keys keys fns fns res []] (if (seq keys) (recur (rest keys) (rest fns) (into res (map (fn [x] [(first keys) x]) (first fns res I am relatively new to Clojure and want to learn how to write idiomatic code. I therefore appreciate any alternative implementation that might help me learn some new things. Stefan -- 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